C 靜態成員的類內初始化

2022-05-04 16:57:07 字數 2242 閱讀 2200

一般來說,關於c++類靜態成員的初始化,並不會讓人感到難以理解,但是提到c++ 靜態成員的"類內初始化"那就容易迷糊了。

我們來看如下**:

1

2 #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$ ./example 

10.5

6.520

C 類內成員初始化

所有標準為c11標準,舊的就不看了。首先說一條指導規則 通常情況下,不應該在類內部初始化成員!無論是否為靜態 是否為常量 是否為int等!統統不建議在類內初始化,因為本質上類只是宣告,並不分配記憶體,而初始化會分配記憶體,類內初始化會將兩個過程混在一起!按順序說。首先靜態成員,用static限制的成...

C 類內成員初始化順序

是類所有的物件的共享的成員,而不是某個物件的成員。它在物件中不占用儲存空間,這個屬性為整個類所共有,不屬於任何乙個具體物件。所以靜態成員不能在類的內部初始化,比如宣告乙個學生類,其中乙個成員為學生總數,則這個變數就應當宣告為靜態變數,應該根據實際需求來設定成員變數。1.成員變數在使用初始化列表初始化...

C 靜態成員初始化

在c 類中,靜態成員一般不允許在類宣告中進行初始化,應該在類的外部進行初始化,例如 class a static int a a 0 初始化方式 void main void 但是有乙個例外,可以為靜態成員提供const 整數型別的類內初始值。要求靜態成員必須是字面值常量型別的constexpr 因...