5
votes

I know why to make default constructor and copy constructor private to implement singleton class in C++. But what I don't understand is that why make copy assignment operator private, because there will not be two existing objects to start with.

My exploration brings two points:

  1. According to Alexandrescu in "Modern C++ Design", the assignment operator to be made private to prevent self-assignment.

  2. Second, according to rule of three, if you define one of ctor, copy ctor and assignment operator for a class, you should define explicitly all three. So, is it a matter of following this rule only.

So, what's your take on this?

2
I am not questioning Alexandrescu's explanation here! I want to know whether there is a technical reason or just to inform the client programmer that assignment is prevented? Because if we don't declare op= then programmers constructs like p1 = p2 would silently pass.Rajendra Uppal
If you use a Singleton, then your design is already so bad, it's laughable that you'd then try to follow the Rule of Three.Puppy
Do you really want to allow this to compile? S::getInstance() = S::getInstance();Martin York

2 Answers

4
votes

I think, the need to prohibit the assignment is more in semantic considerations: as singleton is unique, the assignment for it doesn't have any sense. So if it would be even technically possible to implement assignment in a reasonable way, logically you need to prohibit it anyway.

So exactly because there must be never a need to copy a singleton, the operation has to be prohibited. Otherwise there is a room for confusion and mistakes: the developers will try to use it if it's allowed (and wonder what's wrong).

The good design minimizes the amount of WTFs.

2
votes

No.

In a Singleton you want to manage all possible construction, assignment and destruction. By making all those operations private you actually just prevent others from using them.

Also note that typically copy construction and copy assignment will be declared private to prevent invocation from outside but will not be defined because they are not used in practice... and so if they were the linker would complain.

In C++11 you would declare copy construction and copy assignment as deleted.