一般來說,關於c++類靜態成員的初始化,並不會讓人感到難以理解,但是提到c++ 靜態成員的"類內初始化"那就容易迷糊了。
我們來看如下**:
12 #include3 #include4
using
namespace
std;56
class
example;
1213
14 #include "
example.h"15
16double
example::rate;
17 vectorexample::vec;
18
我們需要判斷上面的靜態資料成員的宣告和定義有沒有錯誤,並解釋原因。
首先,要謹記:通常情況下,不應該在類內部初始化成員,無論是否為靜態成員。
其次,若一定要在類內初始化靜態成員,那麼就必須滿足如下條件才行:
1) 靜態成員必須為字面值常量型別的constexpr。
所謂的字面值型別就是通常遇到的:算術型別,引用,指標等。字面值常量型別就是const型的算術型別,引用,指標等。
所謂的constexpr,就是常量表示式,指值不會改變且在編譯過程中就能得到計算結果的表示式。比如字面值,或者用常量表示式初始化的const物件也是常量表示式。為了幫助使用者檢查自己宣告/定義的變數的值是否為乙個常量表示式,c++11新規定,允許將變數宣告為constexpr型別,以便由編譯器來進行驗證變數是否為常量表示式。
2)給靜態成員提供的初始值,必須為常量表示式
注意:在c++ primer 第五版中說:只能給靜態成員提供const 整數型別的類內初始值,且該const整數型別的初始值必須是常量表示式。我覺得是有誤的!詳情見後面分析。
有了這兩條原則,我們就可以對上面的**進行驗證了。
1)static double rate = 6.5;
顯然不滿足第一條:因為rate不是常量型別。改成constexprt static const double rate = 6.5即可
從這裡也可以看出初始值不一定必須為const 整數型別。
ps: 如果我們不再這裡加入constexprt修飾符的話,編譯器會提示錯誤:error: 『constexpr』 needed for in-class initialization of static data member 『const double example::rate』 of non-integral type [-fpermissive]
大體意思就是,對於非const整數型別的初始值,如果它是常量表示式的話,我們需要手工在前面新增修飾符constexprt。
至於example
.cpp檔案中的定義部分,由於我們已經在類內部進行了初始化,就不需要再在類外部進行定義了。如果非要定義的話,必須採用如下格式:
constexpr const double example::rate; //其中的const是可以刪除的,因為constexprt本身就包含了const
2)static const int vecsize = 20;
vecsize是const int型別的,且為常量表示式——滿足第一條;提供的初始值為20,是乙個常量表示式——滿足第二條!且由於是const int型的,前面可以不用修飾符constexpr。
3)static vectorvec(vecsize);
錯誤!vector是模板不是字面值常量型別,所以不滿足第一條。應該改為 static vectorvec; //僅僅且只能進行宣告,不能定義
然後在example.cpp中
進行定義:
static vectorvec(example
::vecsize)
;現在我們可以在example.cpp
中新增測試**進行測試了:
1 #include "example.h
"2 vectorexample::vec(example::vecsize);
3 constexpr const
double
example::rate;45
intmain()
執行結果:
wanchouchou@wanchouchou-virtual-machine:~/c++/7.5$ ./example10.5
6.520
C 類內成員初始化
所有標準為c11標準,舊的就不看了。首先說一條指導規則 通常情況下,不應該在類內部初始化成員!無論是否為靜態 是否為常量 是否為int等!統統不建議在類內初始化,因為本質上類只是宣告,並不分配記憶體,而初始化會分配記憶體,類內初始化會將兩個過程混在一起!按順序說。首先靜態成員,用static限制的成...
C 類內成員初始化順序
是類所有的物件的共享的成員,而不是某個物件的成員。它在物件中不占用儲存空間,這個屬性為整個類所共有,不屬於任何乙個具體物件。所以靜態成員不能在類的內部初始化,比如宣告乙個學生類,其中乙個成員為學生總數,則這個變數就應當宣告為靜態變數,應該根據實際需求來設定成員變數。1.成員變數在使用初始化列表初始化...
C 靜態成員初始化
在c 類中,靜態成員一般不允許在類宣告中進行初始化,應該在類的外部進行初始化,例如 class a static int a a 0 初始化方式 void main void 但是有乙個例外,可以為靜態成員提供const 整數型別的類內初始值。要求靜態成員必須是字面值常量型別的constexpr 因...