如何在C ++中初始化私有靜態成員?

在C ++中初始化私有靜態數據成員的最佳方法是什麼? 我在頭文件中嘗試了此操做,但它給了我奇怪的連接器錯誤: 函數

class foo
{
    private:
        static int i;
};

int foo::i = 0;

我猜這是由於我沒法從類外部初始化私有成員。 那麼最好的方法是什麼? spa


#1樓

對於之後這個問題的觀衆,我想指出,您應該避免monkey0506的建議code

頭文件用於聲明。 get

頭文件將針對每一個直接或間接#includes .cpp文件進行一次.cpp ,而且任何函數以外的代碼都將在程序初始化時運行在main()以前。 編譯器

經過輸入: foo::i = VALUE; 在頭文件中, foo:i將爲每一個.cpp文件分配值VALUE (不管是什麼),而且這些分配將在運行main()以前以不肯定的順序(由連接器肯定main()進行。 it

若是咱們在其中一個.cpp文件中#define VALUE爲其餘數字怎麼辦? 它將編譯良好,而且在運行程序以前,咱們將沒法知道哪個獲勝。 io

絕對不要將執行的代碼放入標頭中,緣由與您從未#include .cpp文件相同。 編譯

包含衛士(我贊成您應該始終使用)來保護您免受不一樣的傷害:同一頭文件在編譯單個.cpp文件時屢次間接#include d class


#2樓

若是使用標題防禦,也能夠將分配包括在標題文件中。 我將這種技術用於我建立的C ++庫。 得到相同結果的另外一種方法是使用靜態方法。 例如... 變量

class Foo
   {
   public:
     int GetMyStatic() const
     {
       return *MyStatic();
     }

   private:
     static int* MyStatic()
     {
       static int mStatic = 0;
       return &mStatic;
     }
   }

上面的代碼具備不須要CPP /源文件的「好處」。 一樣,這是我用於C ++庫的一種方法。


#3樓

類聲明應該在頭文件中(若是未共享,則在源文件中)。
檔案:foo.h

class foo
{
    private:
        static int i;
};

可是初始化應該在源文件中。
檔案:foo.cpp

int foo::i = 0;

若是初始化在頭文件中,則每一個包含頭文件的文件都將具備靜態成員的定義。 所以,在連接階段,您將獲得連接器錯誤,由於初始化變量的代碼將在多個源文件中定義。 static int i的初始化必須在任何函數以外完成。

注意: Matt Curtis:指出,若是靜態成員變量爲const int類型(例如intboolchar ),則C ++容許簡化上述操做。 而後,您能夠直接在頭文件的類聲明中聲明和初始化成員變量:

class foo
{
    private:
        static int const i = 42;
};

#4樓

對於變量

foo.h:

class foo
{
private:
    static int i;
};

foo.cpp:

int foo::i = 0;

這是由於程序中只能有一個foo::i實例。 它有點像頭文件中的extern int i和源文件中的int i

對於常量 ,能夠將值直接放在類聲明中:

class foo
{
private:
    static int i;
    const static int a = 42;
};

#5樓

int foo::i = 0;

是用於初始化變量的正確語法,可是它必須位於源文件(.cpp)中,而不是標頭中。

由於它是一個靜態變量,因此編譯器僅須要建立一個副本。 您必須在代碼中的某些位置插入「 int foo:i」行,以告訴編譯器將其放置在何處,不然會出現連接錯誤。 若是在標頭中,則將在每一個包含標頭的文件中得到一個副本,所以請從連接器獲取多個已定義的符號錯誤。

相關文章
相關標籤/搜索