8

有人可以证明需要在 Singleton 类实现中私有化赋值运算符吗?

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
};
4

7 回答 7

12

对单例赋值只是一种无意义的操作,因为它应该只存在一个对象。

将赋值运算符设为私有有助于诊断无意义的代码,例如:

Singleton& a = Singleton::Instance();
Singleton& b = Singleton::Instance();
a = b; // Oops, accidental assignment.
于 2011-07-12T15:08:37.470 回答
2

只有一个单身人士。复制它是没有意义的。您需要件事才能使副本保持理智,并且大多数副本操作员需要检查以self==&other确保安全。

这个private技巧是一个技巧。C++0x 做得更好。

开始吐槽...

恕我直言,单身人士在术语上是矛盾的。这是一个愚蠢想法的产物,即一切都必须是一个对象才能被封装。这与 JavaMath.sin(x)等人的脑痛相同。

如果“单例”只是命名空间中的一组自由函数,您的生活会更简单。单例的任何私有“成员”都可以隐藏在 .cpp 中的匿名命名空间中。实现了封装,并且您没有那种繁琐的额外语法。

MyNamespace :: foo ();

代替

MyClass :: instance () .foo ();
于 2011-07-12T15:08:00.793 回答
2

如果您只想要一个实例,则复制构造函数应该是私有的。赋值运算符访问说明符无关紧要,因为无论如何都不可能使用它。

于 2011-07-12T15:09:31.490 回答
1

将赋值运算符设为私有并不会真正改变任何事情,因为您需要两个实例才能进行赋值。它确实与人们可能期望看到的相符;通常,如果复制构造函数是私有的,那么赋值运算符也是如此。声明一个私有赋值运算符只是符合人们的期望。

于 2011-07-12T15:32:34.390 回答
0

当您使用单例时,您实现它的原因是因为您只需要该类对象的一个​​实例。换句话说,无需复制实例,因为您只能拥有一个实例。复制构造函数也是如此。

于 2011-07-12T15:09:25.613 回答
0

我的理由是:如果只有一个实例,那么 operator= 可以毫无问题地定义,因为它不会做任何重要的事情。如果我们将其设为私有,编译器将通过将使用该运算符的任何尝试标记为错误来增加一个安全级别。

顺便说一句,同样的推理也适用于析构函数。

于 2011-07-12T15:12:06.347 回答
0

在单例类模式中继承 boost::noncopyable (privately) 而不是定义私有复制构造和赋值运算符。

于 2011-09-27T07:47:47.473 回答