1. 程式人生 > 其它 >C++中類靜態資料成員的理解

C++中類靜態資料成員的理解

技術標籤:C++

類靜態資料成員是屬於類的,不屬於某一個物件,因此靜態資料並不通過類的建構函式進行初始化。

類中靜態成員的初始化方式有兩種

一、類外初始化

上程式碼

#include <iostream>

using namespace std;

class Foo {
public:
    static int a;
};
int Foo::a = 10;

void print(int &v) {
    cout << v << endl;
}

int main() {
    print(Foo::a);
}

類外初始化就顯示的在類外重新定義類內靜態資料的值。

輸出:

PS E:\cppprojection\prac> cd "e:\cppprojection\prac\" ; if ($?) { g++ demo.cpp -std=c++11 -o demo } ; if ($?) { .\demo }
10

儘管可以使用Foo::al類直接訪問a的值,但是!!!a的訪問許可權仍然收到類中訪問限定符(public,private)的限制

上程式碼

#include <iostream>

using namespace std;

class Foo {
private:
    static int a;
};
int Foo::a = 10;

int main() {
    cout << Foo::a << endl;
}

輸出:

demo.cpp: In function 'int main()':
demo.cpp:14:18: error: 'int Foo::a' is private within this context
     cout << Foo::a << endl;
                  ^
demo.cpp:10:5: note: declared private here
 int Foo::a = 10;
     ^~~

可見即使是靜態成員也受到類訪問限定符的限制。

二、類內初始化

#include <iostream>

using namespace std;

class Foo
{
public:
    const static int a = 10;
};

void print(const int &b) {
    cout << b << endl;
}

int main()
{
    print(Foo::a);
}

但是此時如C++ primer中所說:

上述程式碼的輸出結果是:

C:\Users\DELL\AppData\Local\Temp\cceWu1FV.o:demo.cpp:(.rdata$.refptr._ZN3Foo1aE[.refptr._ZN3Foo1aE]+0x0): undefined reference to `Foo::a'
collect2.exe: error: ld returned 1 exit status

也就是說找不到Foo::a的定義,即使a在類中public的定義過,

如果使用類內初始化的話,正確的做法是如C++primer中所說:

其實我覺得是在類外還要重新宣告一下

正確做法如下

#include <iostream>

using namespace std;

class Foo
{
public:
    const static int a = 10;
};

void print(const int &b)
{
    cout << b << endl;
}

const int Foo::a;  //增加對a的宣告,不能寫成const int Foo::a = 10;否則報錯重複初始化

int main()
{
    print(Foo::a);
}

輸出的正確結果為:

PS E:\cppprojection\prac> cd "e:\cppprojection\prac\" ; if ($?) { g++ demo.cpp -std=c++11 -o demo } ; if ($?) { .\demo }
10