當(dāng)將類的某個數(shù)據(jù)成員聲明為static時必孤,該靜態(tài)數(shù)據(jù)成員只能被定義一次级野,而且要被同類的所有對象共享。各個對象都擁有類中每一個普通數(shù)據(jù)成員的副本娘侍,但靜態(tài)數(shù)據(jù)成員只有一個實例存在辫封,與定義了多少類對象無關(guān)凛辣。靜態(tài)方法就是與該類相關(guān)的绝编,是類的一種行為孕豹,而不是與該類的實例對象相關(guān)框弛。
靜態(tài)數(shù)據(jù)成員的用途之一是統(tǒng)計有多少個對象實際存在辛辨。
靜態(tài)數(shù)據(jù)成員不能在類中初始化,實際上類定義只是在描述對象的藍(lán)圖瑟枫,在其中指定初值是不允許的斗搞。也不能在類的構(gòu)造函數(shù)中初始化該成員,因為靜態(tài)數(shù)據(jù)成員為類的各個對象共享慷妙,否則每次創(chuàng)建一個類的對象則靜態(tài)數(shù)據(jù)成員都要被重新初始化僻焚。
靜態(tài)成員不可在類體內(nèi)進(jìn)行賦值,因為它是被所有該類的對象所共享的膝擂。你在一個對象里給它賦值虑啤,其他對象里的該成員也會發(fā)生變化。為了避免混亂架馋,所以不可在類體內(nèi)進(jìn)行賦值狞山。
靜態(tài)成員的值對所有的對象是一樣的。靜態(tài)成員可以被初始化叉寂,但只能在類體外進(jìn)行初始化萍启。
一般形式:
數(shù)據(jù)類型類名::靜態(tài)數(shù)據(jù)成員名=初值
注意:不能用參數(shù)初始化表對靜態(tài)成員初始化。一般系統(tǒng)缺省初始為0屏鳍。靜態(tài)成員是類所有的對象的共享的成員勘纯,而不是某個對象的成員。它在對象中不占用存儲空間钓瞭,這個屬性為整個類所共有驳遵,不屬于任何一個具體對象。所以靜態(tài)成員不能在類的內(nèi)部初始化山涡,比如聲明一個學(xué)生類超埋,其中一個成員為學(xué)生總數(shù)搏讶,則這個變量就應(yīng)當(dāng)聲明為靜態(tài)變量,應(yīng)該根據(jù)實際需求來設(shè)置成員變量霍殴。
#include "iostream"
using namespace std;
class test
{
private:
int x;
int y;
public:
static int num;
static int Getnum()
{
x+=5; // 這行代碼是錯誤的媒惕,靜態(tài)成員函數(shù)不能調(diào)用非靜態(tài)數(shù)據(jù)成員,要通過類的對象來調(diào)用来庭。
num+=15;
return num;
}
};
int test::num = 10;
int main(void)
{
test a;
cout<<test::num<<endl; //10
test::num = 20;
cout<<test::num<<endl; //20
cout<<test::Getnum()<<endl; //35
cout<<a.Getnum()<<endl; //50
system("pause");
return 0;
}
通過上例可知: x+=5; // 這行代碼是錯誤的
靜態(tài)函數(shù)成員必須通過對象名來訪問非靜態(tài)數(shù)據(jù)成員妒蔚。
另外,靜態(tài)成員函數(shù)在類外實現(xiàn)時候無須加static關(guān)鍵字月弛,否則是錯誤的肴盏。
若在類的體外來實現(xiàn)上述的那個靜態(tài)成員函數(shù),不能加static關(guān)鍵字帽衙,這樣寫就可以了:
int test::Getnum()
{
.........
}
1菜皂、 static成員的所有者是類本身和對象,但是多有對象擁有一樣的靜態(tài)成員厉萝。從而在定義對象是不能通過構(gòu)造函數(shù)對其進(jìn)行初始化恍飘。
2、靜態(tài)成員不能在類定義里邊初始化谴垫,只能在class body外初始化章母。
3、靜態(tài)成員仍然遵循public翩剪,private乳怎,protected訪問準(zhǔn)則。
4前弯、靜態(tài)成員函數(shù)沒有this指針蚪缀,它不能返回非靜態(tài)成員,因為除了對象會調(diào)用它外恕出,類本身也可以調(diào)用询枚。
靜態(tài)成員函數(shù)可以直接訪問該類的靜態(tài)數(shù)據(jù)和函數(shù)成員,而訪問非靜態(tài)數(shù)據(jù)成員必須通過參數(shù)傳遞的方式得到一個對象名剃根,然后通過對象名來訪問。
class Myclass
{
private:
int a,b,c;
static int Sum; //聲明靜態(tài)數(shù)據(jù)成員
public:
Myclass(int a,int b,int c);
void GetSum();
};
int Myclass::Sum=0; //定義并初始化靜態(tài)數(shù)據(jù)成員
Myclass::Myclass(int a,int b,int c)
{
this->a=a;
this->b=b;
this->c=c;
Sum+=a+b+c;
}
void Myclass::GetSum()
{
cout <<"Sum=" <<Sum <<endl;
}
int main(void)
{
Myclass me(10,20,30);
me.GetSum();
system("pause");
return 0;
}
由上例可知前方,非靜態(tài)成員函數(shù)可以任意地訪問靜態(tài)成員函數(shù)和靜態(tài)數(shù)據(jù)成員狈醉。
非靜態(tài)成員函數(shù)Myclass(int a,int b,int c)和GetSum()都訪問了靜態(tài)數(shù)據(jù)成員Sum。
靜態(tài)成員函數(shù)不能訪問非靜態(tài)成員函數(shù)和非靜態(tài)數(shù)據(jù)成員惠险。
關(guān)于靜態(tài)成員函數(shù)苗傅,可以總結(jié)為以下幾點:
- 出現(xiàn)在類體外的函數(shù)定義不能指定關(guān)鍵字static;
- 靜態(tài)成員之間可以相互訪問班巩,包括靜態(tài)成員函數(shù)訪問靜態(tài)數(shù)據(jù)成員和訪問靜態(tài)成員函數(shù)渣慕;
- 非靜態(tài)成員函數(shù)可以任意地訪問靜態(tài)成員函數(shù)和靜態(tài)數(shù)據(jù)成員嘶炭;
- 靜態(tài)成員函數(shù)不能訪問非靜態(tài)成員函數(shù)和非靜態(tài)數(shù)據(jù)成員;
- 由于沒有this指針的額外開銷逊桦,因此靜態(tài)成員函數(shù)與類的全局函數(shù)相比速度上會有少許的增長眨猎;
- 調(diào)用靜態(tài)成員函數(shù),可以用成員訪問操作符(.)和(->)為一個類的對象或指向類對象的指針調(diào)用靜態(tài)成員函數(shù)强经,當(dāng)同一類的所有對象使用一個量時睡陪,對于這個共用的量,可以用靜態(tài)數(shù)據(jù)成員變量匿情,這個變量對于同一類的所有的對象都取相同的值兰迫。靜態(tài)成員變量只能被靜態(tài)成員函數(shù)調(diào)用。靜態(tài)成員函數(shù)也是由同一類中的所有對象共用炬称。只能調(diào)用靜態(tài)成員變量和靜態(tài)成員函數(shù)汁果。