2011-07-12 7 views
5

シングルトンクラスの実装で代入演算子を民営化する必要性を正当化できる人はいますか?シングルトンクラスの代入演算子の民営化の必要性

Singleton& operator=(Singleton const&);をプライベートにするとどのような問題が解決しますか?

class Singleton { 
public: 
    static Singleton& Instance() { 
    static Singleton theSingleton; 
    return theSingleton; 
    } 

private: 
    Singleton(); // ctor hidden 
    Singleton(Singleton const&); // copy ctor hidden 
    Singleton& operator=(Singleton const&); // assign op. hidden 
    ~Singleton(); // dtor hidden 
}; 

答えて

10

割り当ては、単にナンセンス動作です。

Singleton& a = Singleton::Instance(); 
Singleton& b = Singleton::Instance(); 
a = b; // Oops, accidental assignment. 
+2

開発者がa = bを実行してもわかります。両方のオブジェクトがSingletonの同じ静的インスタンスを指しているので、害はありません。したがって、民営化や代入演算子は、シングルトンが期待どおりに動作するための必須条件ではありません。 –

+1

@PrashanthGNこれはノーオペレーションでなければならないのは正しいです。そうすれば 'operator ='は危険ではなく、ナンセンスになります。 –

2

シングルトンは1つのみです。コピーするのは意味がありません。 2つのコピーが正常であることが必要で、ほとんどのコピーオペレータは安全のためにself==&otherを確認する必要があります。

このprivateトリックはハックです。シングルトンは面で矛盾である私見C++0x does it better.

は...

を暴言を開始します。 すべてがカプセル化されるためにはオブジェクトでなければならないという馬鹿げた考えの産物です。これは、Javaを抱いているのと同じ脳みそだ。Math.sin(x)

「シングルトン」が名前空間内のフリー関数のセットである場合、あなたの人生はより簡単になります。シングルトンのプライベート "メンバー"は、.cppの匿名の名前空間に隠すことができます。カプセル化が達成され、その煩雑な構文が不要になります。それの唯一の目的は、これまで存在しなければならないため、シングルトンに

MyNamespace :: foo(); 

代わりに

MyClass :: instance() .foo(); 
+0

代入演算子は実際にコピーには使用されません。 –

+0

しかし、それはコンストラクタを呼び出します。 – 3nixios

+0

'MyNamespace'の関数は、状態を共有する必要があります。これは、正確に1つのオブジェクトが存在するオブジェクトにカプセル化されます。そして、背中はシングルトンです。 *役に立つことはめったにありませんが、時には実際には役に立ちます。もちろん、クラスのこの特定の「シングルトン」パターンを遵守する必要はなく、静的ローカルを返す特別な関数によって状態を管理することもできます。しかし、これは単なる構文上の違いです。 –

0

あなたが唯一のそのクラスのオブジェクトの1つのインスタンスをしたいので、あなたがそれを実装する理由は、シングルトンを使用する場合:代入演算子のプライベートを作る

は、次のようなナンセンスコードを診断するのに役立ちます。つまり、インスタンスを1つしか持てないため、インスタンスのコピーを作成する必要はありません。コピーコンストラクタでも同じです。

2

インスタンスが1つだけ必要な場合は、コピーコンストラクタをプライベートにする必要があります。とにかく使用できないので、代入演算子のアクセス指定子は重要ではありません。

0

私の推論はこれです:1つのインスタンスだけが周囲にある場合、operator =は何も重要ではないので、問題なく定義できます。非公開にした場合、コンパイラはその演算子をエラーとして使用しようとすると、さらにレベルの安全性を追加します。

デストラクタについても同じ理由が当てはまります。

1

割り当て演算子をプライベートにすると、実際には何も変更されません。 2つのインスタンスを割り当てる必要があるためです。人々が見たいと思われるものには が対応しています。コピー のコンストラクタがprivateの場合、代入演算子も同様です。 私的代入演算子を宣言することは、単に人々の期待に対応します。

0

プライベートコピーの作成と代入演算子を定義するよりもシングルトンクラスのパターンでboost :: noncopyable(私的)を継承します。