0

私のプログラムには、プログラムの実行中に作成されたインスタンスが 1 つしかないクラスがたくさんあります。それらは初期化時に一度だけ作成され、閉じるときに一度だけ破棄されます。

これらのクラスはすべて、プログラムのさまざまな部分で使用される非常に幅広い機能を提供する傾向があるため、それらを別のクラスにカプセル化したりポインターを渡したりするのではなく、それらをグローバルな extern として持つことは、非常にクリーンで理解しやすいものです。

このプログラムはマルチスレッドであり、これらすべてのクラスにはアクセス用の独自のミューテックスが含まれています。

このアプローチに問題はありますか? もしそうなら、推奨される代替手段は何ですか。

4

4 に答える 4

2

次のようにシングルトン パターンを使用します。

Foo& foo() { static Foo x; return x; }

これは完全にスレッドセーフです。こちらをご覧ください: G++ 4.6 -std=gnu++0x: Static Local Variable Constructor Call Timing and Thread Safety

現在の規格で保証されています。

さらに、これは静的に初期化されたグローバル変数よりも優れています。これは、上記の変数が複数ある場合、正しい依存関係の順序で遅延して初期化されるためです。

Foo& foo() { static Foo x; return x; }

Bar& bar() { static Bar x; return x; }

Bar::Bar では foo() への呼び出しがあり、Foo シングルトンは Bar の前に作成されます。

グローバル変数を使用した場合:

// Foo.cpp
Foo foo;

// Bar.cpp
Bar bar;

そのような順序は保証されません。

3.6.2 非ローカル変数の初期化

...変数の初期化は、異なる翻訳単位で定義された変数の初期化に関して不定に順序付けられます....

于 2012-04-08T20:21:56.403 に答える
0

クラスでグローバル変数を使用すると、テストが難しくなります。それらの動作は現在、グローバルな状態に依存しているため、それらについて推論することは困難です. 1 つのクラスはグローバル変数に依存します。別のクラスもそれに依存しています。どちらもグローバル変数の状態をいつでも変更できます。本質的に、両方のクラス間に相互依存関係を作成しました。グローバル変数にアクセスするたびに、依存地獄の 1 つのバージョンに一歩近づきます。

それらをポインターとして渡したくないと述べました。実際、私はその方法を好むでしょう。依存関係 (グローバル変数) をメソッドまたはコンストラクターに明示的に渡すことで、それについて世界に伝えます。メソッドに 10 個の依存関係を渡す必要がある場合は、ソリューションを再考することをお勧めします。大変な作業になるかもしれませんが、プログラムのアーキテクチャを改善するのに役立ちます。

あなたのクラスは「非常に幅広い機能を提供する傾向がある」と書いています。これは、実際に必要な機能のみを渡す必要があるように、それらをより小さなコンポーネントに分割する必要があることを示している可能性があります。

私のアドバイスはそれです

  • 特にシングルトンの形で、グローバル変数の使用を避ける必要があります
  • 依存関係の注入について詳しく調べて、依存関係を適切に渡すようにしてください
  • ビデオを見る Don't look for things (Clean Code Talks、Misko Hevery)
于 2012-04-09T13:31:23.863 に答える
0

シングルトンを使用できますが、スレッド セーフであることを確認してください。チュートリアルについては、SINGLETON PATTERN - 1 を参照してください。スレッドの安全性

例は

static SomeSingleton* getInstance()
{
    lock_mutex();
    if(!pInstance_)
        pInstance_ = new SomeSingleton();
    unlock_mutex();
    return pInstance_;
}
于 2012-04-08T20:24:42.397 に答える
-1

c++ には、グローバル オブジェクト コンストラクターの呼び出し順序に大きな問題があります。誰かがそれを「グローバル初期化の大失敗」と呼んでいます。マルチスレッドとは関係ありませんが、初期化と関連しています。プログラムに多数のグローバル オブジェクトがある場合、いくつかの問題が発生する可能性があります (もちろん、その問題を解決します)

パターン「シングルトン」を使用できますが、あなたの場合に役立つかどうかはわかりません

于 2012-04-08T20:38:31.730 に答える