static 成員變量、static 成員函數、類/對象的大小


一、static 成員變量

對於特定類型的全體對象而言,有時候可能需要訪問一個全局的變量。比如說統計某種類型對象已創建的數量。
如果我們用全局變量會破壞數據的封裝,一般的用戶代碼都可以修改這個全局變量,這時可以用類的靜態成員來解決這個問題。
非static數據成員存在於類類型的每個對象中,static數據成員獨立該類的任意對象存在,它是與類關聯的對象,不與類對象關聯。

(1)、static成員的定義

static成員需要在類定義體外進行初始化與定義

(2)、特殊的整型static const成員

整型static const成員可以在類定義體中初始化,該成員可以不在類體外進行定義

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
 
class Test
{
public:
    Test(): a(0) {}
    enum {size1 = 100, size2 = 200};
private:
    const int a;   //只能在構造函數初始化列表中初始化
    static int b;    //在類的實現文件中定義並初始化
    const static int c;    //與 static const int c; 相同。
};

int Test::b = 0; //static成員變量不能在構造函數初始化列表中初始化,因為它不屬於某個對象。
const int Test::c = 0; //注意:給靜態成員變量賦值時,不需要加static修飾符,但要加const

(3)、static成員優點:

static成員的名字是在類的作用域中,因此可以避免與其它類成員或全局對象名字沖突。

可以實施封裝,static成員可以是私有的,而全局對象不可以

閱讀程序容易看出static成員與某個類相關聯,這種可見性可以清晰地反映程序員的意圖。

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
#ifndef _COUNTED_OBJECT_H_
#define _COUNTED_OBJECT_H_

class CountedObject
{
public:
    CountedObject();
    ~CountedObject();
public:
    static int GetCount();
private:
    static int count_;      // 靜態成員的引用性聲明
};


#endif // _COUNTED_OBJECT_H_
 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
#include "CountedObject.h"

int CountedObject::count_ = 0;      // 靜態成員的定義性聲明

CountedObject::CountedObject()
{
    ++count_;
}

CountedObject::~CountedObject()
{
    --count_;
}

int CountedObject::GetCount()
{
    return count_;
}
 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
#include "CountedObject.h"
#include <iostream>
using namespace std;

int main(void)
{
    //cout<<CountedObject::count_<<endl;
    cout << CountedObject::GetCount() << endl;
    CountedObject co1;
    //cout<<CountedObject::count_<<endl;
    cout << CountedObject::GetCount() << endl;
    CountedObject *co2 = new CountedObject;
    //cout<<CountedObject::count_<<endl;
    cout << CountedObject::GetCount() << endl;
    delete co2;
    //cout<<CountedObject::count_<<endl;
    cout << CountedObject::GetCount() << endl;

}

上述程序定義一個靜態成員變量和靜態成員函數,可以通過類名:: 訪問static 成員變量,也可以通過非/靜態成員函數訪問。


二、static 成員函數

static成員函數沒有隱含的this指針
非靜態成員函數可以訪問靜態成員
靜態成員函數不可以訪問非靜態成員(實際上是直接訪問是不可以的,間接地訪問是可以的,比如通過類指針或類引用)

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 
#include <iostream>
using namespace std;

class Test
{
public:
    Test(int y) : y_(y)
    {

    }
    ~Test()
    {

    }

    void TestFun()
    {
        cout << "x=" << x_ << endl; //OK,非靜態成員函數可以訪問靜態成員
        TestStaticFun();
    }
    static void TestStaticFun()
    {
        cout << "TestStaticFun ..." << endl;
        //TestFun();        Error,靜態成員函數不能調用非靜態成員函數
        //cout<<"y="<<y_<<endl;     Error,靜態成員函數不能訪問非靜態成員
    }
    static int x_;      // 靜態成員的引用性說明
    int y_;
};

int Test::x_ = 100;     // 靜態成員的定義性說明

int main(void)
{
    cout << sizeof(Test) << endl;

    return 0;
}

 

三、類/對象大小計算

類大小計算遵循前面學過的結構體對齊原則(參照這里
類的大小與數據成員有關與成員函數無關(空類大小為1個字節)
類的大小與靜態數據成員無關
虛函數對類的大小的影響(參考這里
虛繼承對類的大小的影響(參考這里


參考:

C++ primer 第四版
Effective C++ 3rd
C++編程規范


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM