C++類中談到static,我們可以在類中定義static成員,static成員函數!C++primer里面講過:static成員它不像普通的數據成員,static數據成員獨立於該類的任意對象而存在,每個static數據成員是與類關聯的對象,並不與該類的對象相關聯!這句話可能比較拗口,其實可以這么理解:每個static數據成員可以看成是類的一個對象,而不與該類定義的對象有任何關系!下面我們就來具體看看類中的static數據成員!
談到數據成員,我們最先想到的應該是怎么去定義一個static數據成員,static數據成員是存儲在程序的靜態存儲區,而並不是在棧空間上。既然是static數據成員,所以關鍵字static是必不可少的,例如:
//static.h文件 #include <iostream> #include <string> using namespace std; class Person { private: string name; static int age; public: Person(const string&nm):name(nm) {} void Print() { cout<<name<<" is "<<age<<endl; } }; int Person::age=20; //static.cpp文件 #include "stdafx.h" #include "static.h" #include <iostream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { Person person("tom"); person.Print(); cout<<endl; return 0; }
Person類中定義了一個static數據成員age,注意在類中不能對static數據成員進行初始化,要初始化的話必須在類外進行定義!注意,static數據成員不是通過類構造函數進行初始化的!如上面的代碼所示:在類外定義int Person::age=20;這里前面就不要再加static了。如果類中有多個static數據成員,static數據成員初始化的次序是按照static數據成員在類中的聲明次序進行初始化的,初始化了之后,就可以使用static數據成員了,我們可以通過作用域操作符從類直接調用static數據成員,或者通過對象,引用,或指向該類類型對象的指針間接調用(這種情況下static數據成員必須是public的訪問權限,如果定義在private訪問權限下是不行的)。
說到static數據成員,有一種情況不得不提,那就是特殊的const static成員。如上面所述,類的static成員,像普通數據成員一樣,不能在類的定義體中進行初始化。只能在類外進行初始化。const int 型的static成員便可以在類定義體內部進行初始化。記住一定只能是const int型的,換成const string ,double都不行的。看下面這段代碼:
//static.h頭文件 #include <iostream> #include <string> using namespace std; class Person { private: string name; static const int age=20; static string address; public: Person(const string&nm):name(nm) {} static string Address() { return address; } void Print() { cout<<name<<" is "<<age ; } }; string Person::address="Beijing"; //static.cpp文件 #include "stdafx.h" #include "static.h" #include <iostream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { Person person("tom"); person.Print(); cout<<" and live in "<<person.Address(); cout<<endl; return 0; }
只有age才能在類定義體內進行初始化,address是不行的。這段代碼不能在VC6.0上運行的,它不支持。在vs2008上可以運行。在C++Primer里面有一段注解:const static數據成員在類的定義體中進行了初始化后,還必須在類的定義體之外進行定義。其實這是可要可不要的。上面的代碼就沒有這段代碼實現,其實加上去也是可以的,沒有關系。還有一點,static數據成員的類型可以是該成員所屬的類類型,非static數據成員被限定為其自生類對象的指針或引用。例如:類定義位如下的情況:
class Person { private: string name; static const int age=20; static string address; static Person person1; Person *person2; Person person3; public: Person(const string&nm):name(nm) {} static string Address() { return address; } void Print() { cout<<name<<" is "<<age ; } };
如果沒有定義person3,則能夠順利通過編譯,但是加上了person3就不能通過編譯了!
說完了static成員后,我們再來看看static成員函數,static成員是類的組成部分並不是任何對象的組成部分,因此,static成員函數沒有this指針。我們知道,一般而言,類中的成員函數具有一個附加的隱含實參,即指向該類對象的一個指針。這個隱含實參命名為this。因為static成員函數不是任何對象的組成部分,所以static成員函數就沒有this形參了。由於成員函數聲明為const說明該成員函數不會修改該成員函數所屬的對象,所以static成員函數不能聲明為const。為什么呢?因為static成員函數不是任何對象的組成部分。static成員函數可以直接訪問所屬類的static成員,但是不能直接使用非static成員函數!也不能訪問static const 類型的成員!在上面的代碼中static string Address()函數中如果是return name或者是return age都不行! 好吧,就說這么些吧,如果哪里有不當之處,還請各位指正!