2012-01-23 9 views
0

よく知られているシングルトンデザインパターンの実装のニュアンスについてお話したいと思います。 はここにC++での2つの実装があります。シングルトンクラスの実装バージョン

http://www.codeproject.com/Articles/1921/Singleton-Pattern-its-implementation-with-C

は、別の一つはこれです:

#ifndef __SINGLETON_HPP_ 
#define __SINGLETON_HPP_ 

template <class T> 
class Singleton 
{ 
public: 
    static T* Instance() { 
     if(!m_pInstance) m_pInstance = new T; 
     assert(m_pInstance !=NULL); 
     return m_pInstance; 
    } 
protected: 
    Singleton(); 
    ~Singleton(); 
private: 
    Singleton(Singleton const&); 
    Singleton& operator=(Singleton const&); 
    static T* m_pInstance; 
}; 

template <class T> T* Singleton<T>::m_pInstance=NULL; 

#endif 

私たちは、このバージョンを比較した場合、彼らが好まれているバージョン、最終的にどのような利点と欠点を持っているとん?

+0

はい、パターンですが、使用する必要はありません。あなたは2つの悪のうち小さい方を選ぶでしょう。私はあなたが本当にそれが必要であるとは思わない。 –

+1

@PeterWoodパターンではありません - アンチパターンです –

+2

'__SINGLETON_HPP_'のような名前のインクルードガードを使用すると、実際には醜いことに加えて間違っています。 – 6502

答えて

1

間だけ違いこれらの2つの実装との主な違いは以下のとおりです。

  • 最初はかどうかのポインタをあなたに伝えるために冗長なフラグを追加しますnullなので、必要以上にメモリを消費します。
  • 2番目はシングルトンではありません。Tがパブリックコンストラクタを持つことを阻止するものがないため、シングルトンの制限が解除されます。 (シングルトンが最初の場所で良いアイデアになることはありませんという事実を超えた)それらの両方を持つ

主な問題は、次のとおりです。

  • 建設は、スレッドセーフではありません。 2つのスレッドからInstance()を呼び出すと、2つのオブジェクトが作成される可能性があります。
  • 両方のリークメモリ。 newでオブジェクトを動的に作成しますが、deleteは決して呼び出しません。

C++では、グローバルにアクセス可能なオブジェクトのライフタイムを安全に管理することは非常に困難です。その理由で(とmany others)、私はシングルトンのアンチパターンを避けることをお勧めします。よく管理されたスコープ内にオブジェクトを作成し、必要に応じて参照を渡します。これは、関数が呼び出されたときに初めて作成されます

static Singleton & Instance() { 
    static Singleton instance; 
    return instance; 
} 

、およびC++ 11:あなたは本当にグローバルにアクセス可能なインスタンスをしたい場合は

、その後、ほとんどの場合、最も簡単で安全なオプションがありますコンパイラはこれがスレッドセーフであることを保証する必要があります。残りの問題は、他の静的オブジェクトの前にインスタンスが破棄され、デストラクタがそのオブジェクトにアクセスしようとすると災害が発生することです。

0

基本的に、どちらの実装も同じです。 CodeProjectの上の実装では、2つのことを提供します:あなたが外から「古い」としてシングルトンをマーク(その後、適切に内部からそれを再インスタンス化)することができます

  • シングルトンステータスフラグ、シングルトンさんからの特別なものではありません
  • getInstanceメソッド、視点。しかし、これにより、ある時間後に他人とあなた自身のためにコードをより読みやすくすることができます。


Cat::meow();
Cat::getInstance()->meow()

関連する問題