天天看點

C++類中的static資料成員,static成員函數

  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都不行! 好吧,就說這麼些吧,如果哪裡有不當之處,還請各位指正!

有技術才有魅力,在飄雪的季節守候花開! 【轉自】http://www.cnblogs.com/gysm/archive/2011/09/16/2179277.html   參見:

存儲持續性、作用域和連結性

四種不同對象的生存方式(棧、堆、全局、局部靜态)

轉載于:https://www.cnblogs.com/yyxt/p/4802688.html