3

私はこのようなシングルトンを使用します:

Singleton* single = Singleton::instance();
single->do_it();

私はこのような名前のないクラスを使用します:

single.do_it();

シングルトンパターンには、読み取り可能なエラーメッセージがあること以外に、名前のないクラスに勝る利点はないように感じます。シングルトンの使用は、名前のないクラスオブジェクトを使用するよりも扱いにくいです。まず、クライアントは最初にインスタンスのハンドルを取得する必要があります。第二に、の実装者はSingleton::instance()並行性を考慮する必要があるかもしれません。

では、なぜ、どのようにして、名前のないクラスよりもシングルトンを選択するのでしょうか。

補遺として、名前のないクラスの明白な定義は

class {
    // ...
}single;

私はそれを次のように定義することもできます:

#ifndef NDEBUG
class Singleton__ {   // readable error messages,
#else
class {               // unnamed, clients can't instantiate
#endif
    // ...
}single;

後者のアプローチには、読み取り可能なコンパイラエラーメッセージの利点がありますが、デバッグモードではシングルトンではありません。

4

8 に答える 8

8

最も重要な理由は、名前のないクラスを名前空間スコープに配置できないことだと思います。したがって、以下は有効ではありません (gcc は受け入れますが、警告します。comeau は厳密モードでは受け入れません)。

class { } single;
int main() { }

の型にsingleは、それを参照する別のスコープでその名前を宣言する方法がないため (正確には名前がないため)、リンケージがありませんしかし、それを使用しsingleリンケージ (ここでは外部)を持つ を宣言することは有効ではありません (3.5/8)。リンケージがない main でローカルに定義する必要があります。また、single を関数テンプレートに渡すことも、静的データ メンバーを持つこともできません (それらを定義する方法がないため)。これらすべての制限により、シングルトンの代替としては多かれ少なかれ適用できなくなります。single

于 2008-12-28T03:10:33.020 に答える
4

確かに、C++ でシングルトン オブジェクトを使用する主な理由は、インスタンス メソッド内で「遅延構築」を使用して、初期化順序をある程度制御できるようにするためですか?

例として、私のコードの多くは、ログ メッセージが書き込まれるロガー シングルトンを使用しています。これは、古き良き「グローバル」として何ヶ月も前に始まりましたが、構築前に使用しようとして噛まれた後、現在はシングルトンです:

前...

logger.write("Something bad happened..."); // crash if logger not constructed

...後

 Logger &getLogger()
 {
   static Logger logger_;
   return logger_;
 }

 getLogger().write("Something bad happened...");

私は通常の「シングルトンは悪い」投稿を読んだことがありますが、C++ のより良い代替案を提案する人は見たことがありません。

于 2008-12-28T09:45:11.303 に答える
2

ヘッダーで宣言し、cxx で実装できるシングルトン クラス。したがって、cxx ファイル間で共有できます。各 cxx はオブジェクトの独自のインスタンスを持とうとするため、名前のないクラスではそれを行うことはできません。

于 2008-12-28T02:34:54.027 に答える
1

おそらくコード生成に影響を与えないはずなのに、そのようにコードを変更するのはひどい考えです。遅かれ早かれ、誰かがデバッグまたはリリースで異なるコードを生成するマイナーな調整を行う予定です。その後、デバッグビルドで複製できないリリースクラッシュが発生します。

于 2008-12-28T02:11:05.060 に答える
1

便利ですが、シングルトンは一般的に悪い考えです。交換用のデザインについては、このページを参照してください。

于 2008-12-28T09:20:15.193 に答える
1

あなたの質問から、Singleton パターンの性質と目的を本当に理解していないことがわかります。

多くの「クライアント」がグローバルオブジェクトにアクセスできるようにし、このオブジェクトのインスタンスを 1 つだけ作成したい場合は、シングルトンを使用します。たとえば、ロガー オブジェクトを考えてみましょう。コードのどの部分からでもログを記録できるようにしたいが、プロジェクトにはロガーを 1 つだけにする必要があります。これは、シングルトンに最適な場所です。

あなたの例は、小さなスコープでローカル オブジェクトを作成したかのように見えます。このシングルトンは必要ありません。ただし、コードがより明確になり、読みやすくなります。

于 2008-12-28T12:30:43.293 に答える
0

(エラーの冗長性を除いて)動作の違いがない場合、グローバルインスタンスには1つの追加LOCが必要であり、シングルトンには重要なボイラープレートの束が必要になります。接吻

于 2008-12-28T02:12:22.497 に答える
0

シングルトンを使用します。コンストを使用します。それらすべて1 つの神のクラスで初期化します。静的な初期化順序の大失敗に注意して回避してください: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12

于 2008-12-28T16:41:28.437 に答える