http://blog.163.com/xychenbaihu@yeah/blog/static/13222965520112894854489/
C++靜態數據成員(static member)—靜態成員的初始化不應該在頭文件中,靜態數據成員被類的所有對象共享、包括派生類的對象,在類中可以聲明所屬類自己的靜態數據成員對象、不可以定義非靜態數據成員對象,
最終總結出靜態數據成員的特點有::
1、靜態數據成員僅僅在初始化時,不受訪問權限的約束;
2、靜態數據成員最好不要在.h文件中進行聲明,而是放在.o文件中聲明;
3、靜態數據成員被類的所有對象所共享,包括類的派生類的所有對象;——即派生類和基類共享一個靜態成員。
4、靜態數據成員的類型可是所屬類自己,即在一個類中可以聲明該類自己的類型的靜態成員對象,但是,不可以定義普通的成員對象,(指針可以)
5、在const成員函數中,可以修改static成員變量的值。普通成員變量的值,是不能修改的。
6、static成員函數只能訪問static成員,不能訪問非static成員,並且static成員函數不能定義爲const函數。
詳解
類體中的數據成員的聲明前加上static關鍵字,該數據成員就成爲了該類的靜態數據成員。
和其他數據成員一樣,靜態數據成員也遵守public/protected/private訪問規則。注意::僅僅是初始化時不遵守public/protected/private的規則
同時,靜態數據成員還具有以下特點:
1、靜態數據成員的定義(初始化)不能在頭文件中。
靜態數據成員實際上是類域中的全局變量。所以,靜態數據成員的定義(初始化)不應該被放在頭文件中。
其定義方式與全局變量相同。舉例如下:
xxx.h文件
class base{
private:
static const int _i; //聲明,標準c++支持有序類型在類體中初始化,但vc6不支持。
};
xxx.cpp文件
const int base::_i=10; //定義(初始化)時不受private和protected訪問限制.
注:不要試圖在頭文件中定義(初始化)靜態數據成員。在大多數的情況下,這樣做會引起重複定義這樣的錯誤。即使加上#ifndef #define #endif或者#pragma once也不行。
2、靜態數據成員 被類 的所有對象所共享,包括該類派生類的對象。即派生類對象與基類對象共享基類的靜態數據成員。舉例如下:
class base{
public :
static int _num; //聲明
};
int base::_num=0; //靜態數據成員的真正定義
class derived:public base{
};
main()
{
base a;
derived b;
a._num++;
cout<<"base class static data number _num is"<<a._num<<endl;
b._num++;
cout<<"derived class static data number _num is"<<b._num<<endl;
}
// 結果爲1,2;可見派生類與基類共用一個靜態數據成員。
3、靜態數據成員的類型可以是所屬類的類型,而普通數據成員則不可以。普通數據成員的只能聲明爲所屬類類型的 指針或引用。舉例如下:
class base{
public :
static base _object1; //正確,靜態數據成員
base _object2; //錯誤
base *pObject; //正確,指針
base &mObject; //正確,引用 (這個正確嗎?????)
};
4、靜態數據成員的值在const成員函數中可以被合法的改變,而不破那個數據成員的值,不能在const成員函數中改變。
#include <iostream>
using namespace std;
class Student
{
private:
static int a;
int b;
public:
void change() const;
void setB(int b);
int getB();
static int getA();
};
void Student::change() const
{
a++; //這個可以,因爲a是static成員變量。
b++; //不可以,因爲是const函數
}
int Student::getA()
{
return a;
}
void Student::setB(int b)
{
this->b = b;
}
int Student::getB()
{
return b;
}
int Student::a = 5;
{
Student stu;
stu.setB(10);
stu.change();
cout<<Student::getA()<<endl;
cout<<stu.getB()<<endl;
return 0;
}