abstract:靜態(tài)數(shù)據(jù)成員,用關(guān)鍵字static聲明,該類的所有對(duì)象維護(hù)該成員的同一個(gè)拷貝(包括該類派生類的對(duì)象,即派生類對(duì)象與基類對(duì)象共享基類的靜態(tài)數(shù)據(jù)成員。1、 Static數(shù)據(jù)成員必須在類外部定義,且正好定義一次,static成員屬于類,在類定義時(shí)初始化,而不是像普通數(shù)據(jù)成員在對(duì)象建立時(shí)通過構(gòu)造函數(shù)初始化。用(::)來指明所屬的類 。2、在類的聲明中僅僅對(duì)靜態(tài)數(shù)據(jù)成員進(jìn)行引用性說明,必
靜態(tài)數(shù)據(jù)成員,用關(guān)鍵字static聲明,該類的所有對(duì)象維護(hù)該成員的同一個(gè)拷貝(包括該類派生類的對(duì)象,即派生類對(duì)象與基類對(duì)象共享基類的靜態(tài)數(shù)據(jù)成員。
1、 Static數(shù)據(jù)成員必須在類外部定義,且正好定義一次,static成員屬于類,在類定義時(shí)初始化,而不是像普通數(shù)據(jù)成員在對(duì)象建立時(shí)通過構(gòu)造函數(shù)初始化。用(::)來指明所屬的類 。
2、在類的聲明中僅僅對(duì)靜態(tài)數(shù)據(jù)成員進(jìn)行引用性說明,必須在文件作用域的某個(gè)地方使用類名限定進(jìn)行定義性說明,這時(shí)也可初始化。
(延伸:C++頭文件可以用const int a = 4;或者 static int a = 4;因?yàn)閏onst聲明變量在本文件是局部變量,只在本文件有效。而靜態(tài)變量也是聲明該變量只在本文件有效,所以包含這個(gè)頭文件的多個(gè)源文件里面都有多個(gè)a變量,名字和值都相同。如果是單純的int a,則需要在頭文件里面用extern int a; 而且a不能賦值。)
3、靜態(tài)數(shù)據(jù)成員的類型可以是所屬類的類型,而普通數(shù)據(jù)成員則不可以。普通數(shù)據(jù)成員的只能聲明為所屬類類型的指針或引用
1 classbase{ 2 public : 3 static base _object1;//正確,靜態(tài)數(shù)據(jù)成員 4 base _object2;//錯(cuò)誤 5 base *pObject;//正確,指針 6 base &mObject;//正確,引用 7 };
4、靜態(tài)數(shù)據(jù)成員的值在const成員函數(shù)中可以被合法的改變(const函數(shù)只能禁止該對(duì)象值,卻不能禁止該類的成員值)。舉例如下:
class base{ public: base(){_i=0;_val=0;} mutable int _i; static int _staticVal; int _val; void test() const{//const 成員函數(shù) _i++;//正確,mutable數(shù)據(jù)成員 _staticVal++;//正確,static數(shù)據(jù)成員 _val++;//錯(cuò)誤 } };
5、靜態(tài)數(shù)據(jù)成員可以成為成員函數(shù)的默認(rèn)參數(shù),而普通數(shù)據(jù)成員則不可以。舉例如下:
class base{ public : static int _staticVar; int _var; void foo1(int i=_staticVar);//正確,_staticVar為靜態(tài)數(shù)據(jù)成員 void foo2(int i=_var);//錯(cuò)誤,_var為普通數(shù)據(jù)成員 };
6、一般數(shù)據(jù)成員只能在對(duì)象初始化時(shí)初始化,static成員在類定義時(shí)體外部初始化,而const static數(shù)據(jù)成員可以在類內(nèi)部初始化
靜態(tài)成員函數(shù),在成員函數(shù)前面用static關(guān)鍵字聲明。靜態(tài)函數(shù)只在本文件中有效。
1、static成員函數(shù)屬于類,類外代碼可以使用類名和作用域操作符來調(diào)用靜態(tài)成員函數(shù)。
2、靜態(tài)成員函數(shù) 只能引用屬于該類的靜態(tài)數(shù)據(jù)成員或靜態(tài)成員函數(shù) 。類的靜態(tài)成員函數(shù)不與任何對(duì)象相聯(lián)系,它可以直接訪問類的靜態(tài)數(shù)據(jù)成員,而不能直接訪問類的普通數(shù)據(jù)成員(即非靜態(tài)數(shù)據(jù)成員),因?yàn)槠胀〝?shù)據(jù)成員只有類的對(duì)象存在時(shí)才有意義。
3、static成員函數(shù)沒有this指針,所以只能訪問static數(shù)據(jù)成員。
4、 靜態(tài)成員函數(shù)不可以同時(shí)聲明為virtual、const、volatile函數(shù)。
5、靜態(tài)成員函數(shù)的地址可用普通函數(shù)指針儲(chǔ)存,而普通成員函數(shù)地址需要用類成員函數(shù)指針來儲(chǔ)存。舉例如下:
1 class base{ 2 static int func1(); 3 int func2(); 4 }; 5 int (*pf1)()=&base::func1;//普通的函數(shù)指針 6 int (base::*pf2)()=&base::func2;//成員函數(shù)指針
問:static全局變量與普通的全局變量有什么區(qū)別?static局部變量和普通局部變量有什么區(qū)別?static函數(shù)與普通函數(shù)有什么區(qū)別?
答:全局變量(外部變量)的說明之前再冠以static 就構(gòu)成了靜態(tài)的全局變量。全局變量本身就是靜態(tài)存儲(chǔ)方式, 靜態(tài)全局變量當(dāng)然也是靜態(tài)存儲(chǔ)方式。這兩者在存儲(chǔ)方式上并無不同。這兩者的區(qū)別雖在于非靜態(tài)全局變量的作用域是整個(gè)源程序, 當(dāng)一個(gè)源程序由多個(gè)源文件組成時(shí),非靜態(tài)的全局變量在各個(gè)源文件中都是有效的。 而靜態(tài)全局變量則限制了其作用域, 即只在定義該變量的源文件內(nèi)有效, 在同一源程序的其它源文件中不能使用它。由于靜態(tài)全局變量的作用域局限于一個(gè)源文件內(nèi),只能為該源文件內(nèi)的函數(shù)公用, 因此可以避免在其它源文件中引起錯(cuò)誤。
從以上分析可以看出,把局部變量改變?yōu)殪o態(tài)變量后是改變了它的存儲(chǔ)方式即改變了它的生存期。把全局變量改變?yōu)殪o態(tài)變量后是改變了它的作用域, 限制了它的使用范圍。static函數(shù)與普通函數(shù)作用域不同。僅在本文件。只在當(dāng)前源文件中使用的函數(shù)應(yīng)該說明為內(nèi)部函數(shù)(static),內(nèi)部函數(shù)應(yīng)該在當(dāng)前源文件中說明和定義。對(duì)于可在當(dāng)前源文件以外使用的函數(shù),應(yīng)該在一個(gè)頭文件中說明,要使用這些函數(shù)的源文件要包含這個(gè)頭文件。
總結(jié):
static全局變量與普通的全局變量有什么區(qū)別:static全局變量只初使化一次,防止在其他文件單元中被引用;
static局部變量和普通局部變量有什么區(qū)別:static局部變量只被初始化一次,下一次依據(jù)上一次結(jié)果值;
static函數(shù)與普通函數(shù)有什么區(qū)別:static函數(shù)在內(nèi)存中只有一份,沒有this指針,普通函數(shù)在每個(gè)被調(diào)用中維持一份拷貝