3 回答

TA貢獻1780條經驗 獲得超1個贊
從根本上講,這是因為靜態成員必須精確地定義在一個翻譯單元中,以便不違反單一定義規則。如果語言允許類似以下內容:
struct Gizmo
{
static string name = "Foo";
};
然后name將在#include該頭文件的每個轉換單元中定義。
C ++確實允許您在聲明中定義不可分割的靜態成員,但是您仍然必須在單個翻譯單元中包含一個定義,但這只是一個捷徑或語法糖。因此,這是允許的:
struct Gizmo
{
static const int count = 42;
};
只要a)表達式是const整數或枚舉類型,b)可以在編譯時對表達式求值,并且c)仍然存在不違反一個定義規則的定義:
文件:gizmo.cpp
#include "gizmo.h"
const int Gizmo::count;

TA貢獻1765條經驗 獲得超5個贊
在C ++中,自開始以來,初始化器的存在是對象定義的專有屬性,即,帶有初始化器的聲明始終是定義(幾乎總是)。
如您所知,C ++程序中使用的每個外部對象都必須在一個翻譯單元中定義一次,并且只能定義一次。允許類內初始化程序用于靜態對象將立即違反此約定:初始化程序將進入頭文件(通常在類定義所在的位置),從而生成同一靜態對象的多個定義(每個包含頭文件的翻譯單元一個定義) )。當然,這是不可接受的。因此,靜態類成員的聲明方法完全是“傳統”的:您僅在頭文件中聲明它(即不允許初始化器),然后在您選擇的翻譯單元中定義它(可能使用初始化器) )。
此規則的一個例外是整數或枚舉類型的const靜態類成員,因為此類條目可以用于整數常量表達式(ICE)。ICE的主要思想是在編譯時對其進行評估,因此不依賴于所涉及對象的定義。這就是為什么整數或枚舉類型可能會出現此異常的原因。但是對于其他類型,這只會與C ++的基本聲明/定義原理相矛盾。
- 3 回答
- 0 關注
- 1208 瀏覽
添加回答
舉報