2009-09-07 11 views
8

乾杯は、C++の静的インスタンスを介したシングルトン - ソースファイルまたはヘッダーファイル?

私は「例によるプログラミングゲームAI」でこのコードの塊に走った:

/* ------------------ MyClass.h -------------------- */ 
#ifndef MY_SINGLETON 
#define MY_SINGLETON 

class MyClass 
{ 
private: 

    // member data 
    int m_iNum; 

    //constructor is private 
    MyClass(){} 

    //copy ctor and assignment should be private 
    MyClass(const MyClass &); 
    MyClass& operator=(const MyClass &); 

public: 

    //strictly speaking, the destructor of a singleton should be private but some 
    //compilers have problems with this so I've left them as public in all the 
    //examples in this book 
    ~MyClass(); 

    //methods 
    int GetVal()const{return m_iNum;} 
    static MyClass* Instance(); 
}; 

#endif 

/* -------------------- MyClass.cpp ------------------- */ 

//this must reside in the cpp file; otherwise, an instance will be created 
//for every file in which the header is included 
MyClass* MyClass::Instance() 
{ 
    static MyClass instance; 

    return &instance; 
} 

私は著者静的に宣言された変数によって問題-の-事実文で混乱していますヘッダ内の関数の中で、複数の独立した静的変数instanceを宣言します。私は普通の実装であるgetInstance()の機能でこの動作を見たことはないと思います(ただし、ポインタを使って遊んで最初の使用時にシングルトンを初期化するのを除いて)。私は自分の仕事にGCCを使用しています。

だから、規格は何を言っているのですか?非準拠のコンパイラは何を言いますか?著者のステートメントが正しいかどうか、もしそうなら、getInstance()がヘッダーで宣言されていれば、複数のインスタンスを作成するコンパイラの名前を付けることができますか?

+4

シングルトンを実装する方法と、C++のスレッドセーフティについての素晴らしい説明は、このホワイトペーパーで見つけることができます。 http://www.aristeia.com/Papers/DDJ%5FJul%5FAug%5F2004%5Frevised .pdf –

答えて

10

C++では、インライン関数が静的変数を持つことを妨げるものはありません。コンパイラは、その変数をすべての変換単位間で共通にする必要があります(テンプレートインスタンス化静的クラスメンバおよび静的関数変数の場合と同じです)。 7.1.2/4

の変数は、常に同じオブジェクトを参照します。

Cでは、インライン関数は静的変数を持つことはできません(内部リンケージを持つオブジェクトへの参照もありません)。

+0

つまり、myclass.h内の「静的インライン関数」で定義された「静的変数」は、リンクされた結果コードに1回だけ表示され、ソースファイル間で共有されます(main.cpp、myclass.cpp plumber.cppに合っていますか?)上記のコードからヘッダーに移動:: Instance()は、同じインスタンスが別の.cppファイルに返されることを保証しますか? –

+0

コンパイラが準拠している限り。私は何の問題も覚えておらず、テンプレートには易しさが必要なので、私はその点について恐れることはありません。 – AProgrammer

+1

これに関する最近の問題や、VC6やGCC 2.95については聞いたことがありません。 – MSalters

1

私はOPがVS2008で投稿されたコードを4通りの方法で試しましたが、MyClass::Instance()の静的インスタンスMyClassに問題はないようです。

  1. Instance()は MyClass.cppに定義されています。これは すべてがうまくている通常の方法です。
  2. Instance()は、 クラス宣言内でのみ定義されます。これは の代替品で、すべて問題ありません。
  3. Instance()が定義されています。inline クラス外ですが、ヘッダーには とすべてが問題ありません。 3.として
  4. が、inlineと なしリンカが Instance()

のみとめ定義が存在すると言う私は、本の著者は、上記4と懸念しているとのMyClassの静的インスタンスがされることを知っていると思いますコンパイルしてリンクするプログラムで世話をしています。

+0

私はあなたを受け入れたとマークしたいと思いますが、私はすでにAProgrammerでそれを行いました。だからここには非常に明確な理由があるだけです。 –

関連する問題