Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does "operator=" return type matter if I want to make the class non-copyable?

Suppose I have a class that doesn't support memberwise copying so I don't want to preserve compiler-implemented copy-constructor and assignment operator. I also don't want to implement those because either

  1. doing so takes extra effort and I don't need those operations in my class or
  2. those operations won't make sense in my class

so I want to prohibit them. To do so I'll declare them private and provide no implementation:

class NonCopyable {
private:
   NonCopyable( const NonCopyable& ); //not implemented anywhere
   void operator=( const NonCopyable& ); //not implemented anywhere
};

Now I can select any return type for operator=() member function. Will it matter which return type I select?

like image 655
sharptooth Avatar asked Dec 26 '11 08:12

sharptooth


1 Answers

No, the return type doesn't matter.

The C++ standard does not impose any requirements on the return type for copy assignment special member functions that you declare yourself. It just needs to be an operator=() that acccepts "exactly one parameter of type X, X&, const X&, volatile X& or const volatile X&".†† Therefore, void operator=( const NonCopyable& ); is still a copy assignment operator (a user-declared one, to be specific).

Because you have in fact supplied your own copy assignment operator, it will surpress the generation of the default copy assignment operator. This forces all calls to NonCopyable's copy assignment operator to resolve to yours, causing any attempts to use the copy assignment operator to fail to compile since it's declared private.

class Foo : NonCopyable
{
};

int main()
{
    Foo a;
    Foo b;
    // Compiler complains about `operator=(const NonCopyable&)`
    // not accessible or something like that.
    a = b;
}

And since I'll never be able to actually use it, it doesn't matter that it's not exactly the canonical copy assignment operator. If I tried to use the copy assignment operator it would result in a compiler error, which is exactly what you want.


† Of course, it does matter, stylistically speaking, if the copy assignment operator actually does something. Generally you want your operators to behave just like the built-in ones, so returning a X& is good practice when you're actually doing assignment.

†† C++ Standard: 12.8 Copying class objects [class.copy]

9 A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const X&, volatile X& or const volatile X&.

like image 154
In silico Avatar answered Nov 02 '22 12:11

In silico