2016-07-28 8 views
3

特定のインスタンスのコンストラクタ内で静的メンバー変数を初期化します。それは悪い考えですか?インスタンスのコンストラクタ内で静的メンバーを初期化する

状況は次のとおりです。このクラスのすべてのインスタンスが共有する静的メンバー変数があります。通常は、静的初期化子を使用します。しかし、私は、コンストラクタが呼び出されるまで静的オブジェクトを構築するのに必要な情報を持っていません。もちろん、コンストラクタが呼び出されるたびに新しいオブジェクトを作成したくないので、このようなことをしたいと思います。私はもちろんxyzの知っている

class Foo 
{ 
    static Bar * bar; 
    Foo(Xyz xyz); 
}; 

Bar * Foo::bar = nullptr; 

Foo::Foo(Xyz xyz) 
{ 
    if (Foo::bar == nullptr) 
    { 
     // initialize static bar 
     Foo::bar = new Bar(xyz); 
    } 
} 

Fooのコンストラクタに異なる呼び出しに対して異なることmigth。それは私には関係ありません。

この悪いソフトウェア設計ですか?コンストラクタ内で静的オブジェクトを初期化するのはちょっと奇妙です。しかし、それはシングルトンデザインパターンとそれほど違いはありません。だから多分それは大丈夫ですか?コメントの男性のための

EDIT

感謝。人々はこのデザインのファンではないようです。私はFooの最初のインスタンス化の前にBarを作成し、FooのコンストラクタのパラメータとしてBar *を渡すように変更します。各FooにはBarへのポインタがあり、すべてFooがすべて同じBarを指していることを確認します。それは良いですか?

+1

あなたが初期化を行うことはありませんのでご注意ください。あなたは割り当てをします。 – NathanOliver

+0

_initialization_に使用する値はどのようにして取得できますか?実行時にのみ利用可能ですか?サンプルはコンパイルされません。 –

+3

シングルスレッドはOKです。マルチスレッド競合状態。 –

答えて

1

この悪いソフトウェア設計ですか?

一般的にそうであると考えられます。 シングルトンパターンまたはこのような静的変数を持つ理由が、不良設計とみなされる理由はたくさんあります。


しかし、それはシングルトンデザインパターンと大差ありません。だから多分それは大丈夫ですか?

あなたは本当にあなたがむしろScott Meyer's techniqueを使用する必要がありますSingletonパターンということにしたい場合:

class Foo 
{ 
    static Bar* bar(Xyz xyz) { 
     static Bar barInstance(xyz); 
     return &barInstance; 
    } 
    Foo(Xyz xyz) : xyz_(xyz) {} 

    void baz() { 
     Bar* b = bar(xyz_); 
     // use b ... 
    } 

private: 
    Xyz xyz_; 
}; 

このコードは、スレッドセーフである、とnullptrをチェックする必要がなくなります。 Barものの


それ自身にシングルトンを構成し、必要な時はいつでもあなたはFooでそれを使用する必要があります。

class Bar { 
public: 
    static Bar& getInstance(Xyz xyz) { 
     static Bar barInstance(xyz); 
     return &barInstance; 
    } 

private: 
    Bar(Xyz xyz) : xyz_(Xyz) {} 
    Bar(const Bar&) delete; 
    Bar(Bar&&) delete; 
    Bar& operator=(const Bar&) delete; 
    Bar& operator=(Bar&) delete; 

    Xyz xyz_; 
}; 

class Foo { 
public: 
    Foo(Xyz xyz) barRef(Bar::getInstance(xyz)) { 
             // ^^^ Notice 1st instance of Foo created 
             //  wins to create the Bar actually 
    } 
private: 
    Bar& barRef; 
}; 
+0

* "しかし、コンストラクタが呼び出されるまで静的オブジェクトを構築するために必要な情報はありません" * ... – Jarod42

+1

@ Jarod42これは設計に欠陥があることを示す指標であり、 'Bar'は'Foo'との静的な関係。私は_real_シングルトンパターンとの違いを明確にしようとしています。 –

関連する問題