靜態常量字符串(類成員)

我想要一個類的私有靜態常量(在這種狀況下是形狀工廠)。 函數

我想要些相似的東西。 this

class A {
   private:
      static const string RECTANGLE = "rectangle";
}

不幸的是,我從C ++(g ++)編譯器中收到各類錯誤,例如: spa

ISO C ++禁止初始化成員「 RECTANGLE」 設計

非整數類型'std :: string'的靜態數據成員的無效的類內初始化 code

錯誤:將「 RECTANGLE」設爲靜態 內存

這告訴我,這種成員設計不符合該標準。 您如何在沒有使用#define指令的狀況下擁有私有文字常量(或也許是公共的)(我想避免數據全局性的醜陋!) 字符串

任何幫助表示讚揚。 get


#1樓

您必須在類定義以外定義靜態成員,而後在其中提供初始化程序。 編譯器

第一 string

// In a header file (if it is in a header file in your case)
class A {   
private:      
  static const string RECTANGLE;
};

而後

// In one of the implementation files
const string A::RECTANGLE = "rectangle";

您最初嘗試使用的語法(類定義內的初始化程序)僅適用於整數和枚舉類型。


從C ++ 17開始,您還有另外一個選擇,與原始聲明很是類似:內聯變量

// In a header file (if it is in a header file in your case)
class A {   
private:      
  inline static const string RECTANGLE = "rectangle";
};

無需其餘定義。

或者,您能夠在此變體中將其聲明爲constexpr而不是const 。 顯式inline將再也不是必需的,由於constexpr暗示了inline


#2樓

若要使用該類內初始化語法,該常數必須是經過常數表達式初始化的整數或枚舉類型的靜態const。

這是限制。 所以,在這種狀況下,您須要在類外部定義變量。 引用@AndreyT的答案


#3樓

這只是額外的信息,可是若是您確實但願將字符串包含在頭文件中,請嘗試如下操做:

class foo
{
public:
    static const std::string& RECTANGLE(void)
    {
        static const std::string str = "rectangle";

        return str;
    }
};

雖然我懷疑這是值得推薦的。


#4樓

當前標準僅容許對靜態常數積分類型進行此類初始化。 所以,您須要按照AndreyT的說明進行操做。 可是,將經過新的成員初始化語法在下一個標準中提供該功能


#5樓

在類定義內部,您只能聲明靜態成員。 它們必須在類以外定義 。 對於編譯時積分常量,該標準例外,您能夠「初始化」成員。 可是,這仍然不是一個定義。 例如,沒有定義就沒法使用該地址。

我想說起的是,我沒有看到使用std :: string而不是const char [] 做爲常量的好處。 std :: string很不錯,除了它之外,它都須要動態初始化。 因此,若是你寫相似

const std::string foo = "hello";

在名稱空間範圍內,foo的構造函數將在執行main開始以前當即運行,而且此構造函數將在堆內存中建立常量「 hello」的副本。 除非您真的須要RECTANGLE成爲std :: string,不然您也能夠編寫

// class definition with incomplete static member could be in a header file
class A {
    static const char RECTANGLE[];
};

// this needs to be placed in a single translation unit only
const char A::RECTANGLE[] = "rectangle";

那裏! 沒有堆分配,沒有複製,沒有動態初始化。

乾杯

相關文章
相關標籤/搜索