【轉】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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章