5

私が次のアーキテクチャを持っていると想像してみましょう:

  • Dodoのシングルトンクラスlibdodo
  • メインプログラムがリンクされlibdodoていlibponnyます; と呼ばれるメインプログラムDodo::instance()
  • Ponny作成されたクラスlibponnyDodoシングルトン用のヘッダーがあります

mainwindow.cpp

    #include "shared/dodo/dodo.h"
    // ...
    Dodo::instance()->setNumber(91);

そして、この呼び出しの後、Ponnyクラス(ponny.cpp)が作成されます

ponny.cpp

    #include "shared/dodo/dodo.h"
    // ...
    bool is = (Dodo::instance()->number() == 91);
    // Will `is` be true?

だから、私はこのようにそれを行うことができますか?

4

2 に答える 2

3

シングルトンの動作の定義はライブラリ内にあるため、シングルトンインスタンスは一意であり、作成されたコンパイルユニット内に存在します。

libdodoあなたが持っているところに、があるとしましょうDodo.cpp

static Dodo& Dodo::instance()
{
    static Dodo dodo;
    return dodo;
}

ローカル静的変数は、実行が最初に宣言に達したときに初期化されることに注意してください。この場合、Dodo::instanceが最初に呼び出されると、このようなシングルトンの遅延初期化に問題が発生しない可能性があります。

ここで役割を果たす唯一の事実はスレッドセーフです。これは、より多くのスレッドDodo::instance()が初めて呼び出されるときに競合状態が発生する可能性があるためです。詳細については、以下をお読みになることをお勧めします。
この質問: この記事のシングルトンとマルチスレッド: C ++スコープの静的初期化は、意図的にスレッドセーフではありません。 そして、この質問もあなたを助けるかもしれません: C++でのシングルトンのスレッドセーフな怠惰な構築


また、C ++ 11(§6.7.4)では、静的変数の初期化はスレッドセーフであることが保証されていることに注意してください。

変数の初期化中に制御が宣言に同時に入る場合、同時実行は初期化の完了を待機する必要があります。

これは、このような怠惰な初期化がちょっと防弾になることを意味します;)

于 2013-01-30T15:35:35.847 に答える
2

シングルトンインスタンスはグローバルです。それが本当にあなたが求めているものであるならば、グローバルはDLL/共有オブジェクトの境界を越えて共有することができます。

また、このクラスの定義が1つしかないことを保証する単一定義規則を理解する必要があります。したがって、クラス内の静的メンバーにはインスタンスが1つだけあります。

于 2013-01-30T16:11:43.053 に答える