C/C++ static member variable 用法與初始化方式

本篇 ShengYu 介紹 C/C++ static member variable 用法與初始化方式,static member variable 初始化方式非常特殊也容易忘記。

C/C++ static member variable

static 放在 class 的 member variable 之前,稱為靜態成員變數 (static member variable),如下範例中的 counter,

1
2
3
4
5
6
7
class Object {
public:
Object() {
}
private:
static int counter;
};

C/C++ static member variable 初始化方式

static class member 無法直接在 class 內初始化,如下範例所示,Object class 裡的 static int counter = 0; 在 class 內初始化 initialize static 成員變數會造成編譯錯誤,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
using namespace std;

class Object {
public:
Object() {
++counter;
cout << "counter = " << counter << endl;
}

static int getCounter() { return counter; }
private:
static int counter = 0;
};

int main() {
Object obj1;
Object obj2;
Object obj3;
cout << Object::getCounter() << endl;
return 0;
}

編譯錯誤訊息如下,訊息明確地顯示 C++ 禁止在 class 裡初始化 static member,

1
2
cpp-static.cpp:13:26: error: ISO C++ forbids in-class initialization of non-const static member ‘Object::counter’
static int counter = 0;

那不寫初始化動作呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
using namespace std;

class Object {
public:
Object() {
++counter;
cout << "counter = " << counter << endl;
}

static int getCounter() { return counter; }
private:
static int counter;
};

int main() {
Object obj1;
Object obj2;
Object obj3;
cout << Object::getCounter() << endl;
return 0;
}

也是會編譯錯誤,編譯錯誤訊息如下,會在連結 (link) 時期出現 undefined reference 的錯誤,

1
2
3
4
5
6
7
/tmp/ccbvdWOg.o: In function `Object::Object()':
cpp-static.cpp:(.text._ZN6ObjectC2Ev[_ZN6ObjectC5Ev]+0xf): undefined reference to `Object::counter'
cpp-static.cpp:(.text._ZN6ObjectC2Ev[_ZN6ObjectC5Ev]+0x18): undefined reference to `Object::counter'
cpp-static.cpp:(.text._ZN6ObjectC2Ev[_ZN6ObjectC5Ev]+0x1e): undefined reference to `Object::counter'
/tmp/ccbvdWOg.o: In function `Object::getCounter()':
cpp-static.cpp:(.text._ZN6Object10getCounterEv[_ZN6Object10getCounterEv]+0x6): undefined reference to `Object::counter'
collect2: error: ld returned 1 exit status

以下示範正確的 static member variable 初始化寫法,這個範例是計算這個 Object class 被生成了幾個實體 (instance),
靜態成員變數初始化寫在 class 外面,如範例中的 int Object::counter = 0;
靜態成員變數這個技巧概念也被應用在 std::shared_ptr 上,用來追蹤有幾個指標共享一塊記憶體,
另外補充靜態成員函式裡存取的所有變數都要是 static,如下例中的 getCounter()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;

class Object {
public:
Object() {
++counter;
cout << "counter = " << counter << endl;
}

static int getCounter() { return counter; }
private:
static int counter;
};

int Object::counter = 0; // initializing the static int

int main() {
Object obj1;
Object obj2;
Object obj3;
cout << Object::getCounter() << endl;
return 0;
}

以上就是 C/C++ static member variable 用法與初始化方式的介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它參考
How to initialize private static members in C++?
https://www.tutorialspoint.com/how-to-initialize-private-static-members-in-cplusplus

其它相關文章推薦
如果你想學習 C++ 相關技術,可以參考看看下面的文章,
C/C++ static 的 5 種用法
C/C++ 新手入門教學懶人包
std::vector 用法與範例
std::deque 介紹與用法
std::queue 用法與範例
std::map 用法與範例
std::unordered_map 用法與範例
std::sort 用法與範例
std::shared_ptr 用法與範例