簡體   English   中英

C ++內聯初始化靜態const char *

[英]C++ inline initialization of a static const char*

為什么我不能在頭文件中初始化靜態const char *? 在我的代碼中,我在我的類頭中:

static const char* xml_ID_TAG;

在cpp中:

const char* Class::xml_ID_TAG = "id";

xml_ID_TAG變量包含XML文檔的屬性字符串。 因為它是靜態的,const,原始類型(char *)等...我無法弄清楚為什么編譯器禁止編寫類似的東西:

static const char* xml_ID_TAG = "id";

我正在使用MSVC2013編譯器,給出上面的錯誤示例:“錯誤:具有類內初始化程序的成員必須是const”

一般來說,您必須在一個翻譯單元中定義靜態成員,並且該語言通過禁止您在周圍的類定義中為此類成員編寫初始化器來幫助強制執行此操作:

struct T
{
   static int x = 42;
   // ^ error: ISO C++ forbids in-class initialization of
   // non-const static member 'T::x'
};

但是,為方便起見,對常量進行了特殊的例外處理:

struct T
{
   static const int x = 42;
   // ^ OK
};

請注意,在大多數情況下,您仍然需要定義常量(在.cpp文件中將是最佳位置):

const int T::x;

[C++11: 9.4.2/3]:]如果非易失性const static數據成員是整數或枚舉類型,它在類定義中的聲明可以指定一個括號或等於初始化器 ,其中每個初始化器-clause賦值表達式,是一個常量表達式(5.19)。 可以使用constexpr說明符在類定義中聲明文字類型的static數據成員; 如果是這樣,它的聲明應指定一個大括號或等於初始化器 ,其中作為賦值表達式的每個initializer子句都是一個常量表達式。 [注意:在這兩種情況下,成員可能會出現在常量表達式中。 -end note]如果在程序中使用odr-used (3.2)並且命名空間作用域定義不包含初始化程序,則仍應在命名空間作用域中定義該成員。


現在,您的成員不是int ,甚至const char* const也不是“整數類型”:

struct T
{
   static const char* const str = "hi";
   // ^ error: 'constexpr' needed for in-class initialization of
   // static data member 'const char* const T::str' of non-integral type
};

但它一個“字面型”; 你的結果是,如果你這樣寫:

static constexpr const char* const xml_ID_TAG = "id";
//     ^^^^^^^^^             ^^^^^

你應該沒問題。 (注意, 在C ++ 17之前您仍然需要定義它 。)

無論如何,這可能更有意義:你為什么要改變指針?

因為它是[...] const ” - 不。

你需要const char* const - 假設你使用的是C ++ 11。

否則,您必須將定義放在cpp文件中。

請參閱: 如何在C ++中初始化靜態const成員?

因為字符串文字(例如"id" )是按文件編譯單元存儲的。 因此,如果它們位於頭文件中,則為包含它的每個源文件存儲不同的實例。 所以你的'初始化'試圖在每個編譯單元的static變量中存儲不同的值#include s it ..

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM