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個位元組)
類的大小與靜態數據成員無關
虛函數對類的大小的影響(參考這裡)
虛繼承對類的大小的影響(參考這裡)


TAG:程序員小新人學習 |