8

Can someone justify the need of privatizing the assignment operator in a Singleton class implementation?

What problem does it solve by making Singleton& operator=(Singleton const&); private?

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
};
Prashanth G N
  • 145
  • 2
  • 9

7 Answers7

12

Assignment on a singleton is simply a nonsense operation since only one object of it should ever exist.

Making the assignment operator private helps diagnose nonsense code such as the following:

Singleton& a = Singleton::Instance();
Singleton& b = Singleton::Instance();
a = b; // Oops, accidental assignment.
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • 3
    I understand even if a developer does a = b; there is no harm as both objects point to the same static instance of Singleton. So privatization or assignment operator is not a must for a singleton to behave as expected. – Prashanth G N Jul 13 '11 at 13:55
  • 1
    @PrashanthGN It’s correct that this should be a no-operation so having `operator=` isn’t dangerous, just nonsense. – Konrad Rudolph Jul 13 '11 at 14:02
2

There's only one singleton. It makes no sense to copy it. You need two things for a copy to be sane and most copy operators need to check for self==&other in order to be safe.

This private trick is a hack. C++0x does it better.

Begin rant...

IMHO a Singleton is a contradiction in terms. It's a product of the silly idea that everything must be an object in order to be encapsulated. It's the same brainache that bore Java's Math.sin(x) et al.

Your life will be simpler if the "singleton" is simply a set of free functions in a namespace. Any private "members" of the singleton can be hidden in an anonymous namespace in the .cpp. Encapsulation achieved, and you don't have that cumbersome extra syntax.

MyNamespace :: foo ();

instead of

MyClass :: instance () .foo ();
spraff
  • 32,570
  • 22
  • 121
  • 229
  • The assignment operator isn't really used for copying, though. – James McNellis Jul 12 '11 at 15:09
  • But it calls the constructor. – 3nixios Jul 12 '11 at 15:11
  • The functions in `MyNamespace` may still need to share state, which would then be encapsulated in an object of which exactly one object exists. And back is the singleton. It is *rarely* useful, but sometimes it *is* actually useful. Of course, there’s no need to adhere to this particular `Singleton` pattern of a class, the state can also be managed by a special function returning a static local. But this is just a syntactic difference. – Konrad Rudolph Jul 12 '11 at 15:16
  • Free functions can still share state. In the extreme case they're called "globals", but you can hide them in an anonymous namespace in the .cpp. Objects are only useful when the instances are distinct. When you've got a hammer, every problem looks like OOP. – spraff Jul 12 '11 at 15:18
2

If you only want one instance, the copy constructor should be private. The assignment operator access specifier does not matter, because it will be impossible to use anyway.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
1

Making the assignment operator private doesn't really change anything, since you need two instances to be able to assign. It does correspond to what people may expect to see; it's usual that if the copy constructor is private, the assignment operator is as well. Declaring a private assignment operator simply corresponds to people's expectations.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
0

When you use a singleton the reason you implement it is because you only want one instance of an object of that class. In other words there is no need to make a copy of the instance because you can only have one instance. It is the same for the copy constructor.

Armand
  • 9,847
  • 9
  • 42
  • 75
0

My reasoning is this: if only one instance may be around, operator= could be defined without problem, since it will not do anything significant. if we make it private, the compiler will add one more level of safety by flagging any attempt to use that operator as an error.

The same reasoning holds for the destructor, by the way.

sergio
  • 68,819
  • 11
  • 102
  • 123
0

Inherit boost::noncopyable (privately) in singleton class pattern than to define private copy construction and assignment operator.