Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Macros to disallow class copy and assignment. Google -vs- Qt

Tags:

c++

To disallow copying or assigning a class it's common practice to make the copy constructor and assignment operator private. Both Google and Qt have macros to make this easy and visible. These macros are:

Google:

#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
  TypeName(const TypeName&);   \
  void operator=(const TypeName&) 

Qt:

#define Q_DISABLE_COPY(Class) \
  Class(const Class &); \     
  Class &operator=(const Class &);

Questions: Why are the signatures of the two assignment operators different? It seems like the Qt version is correct. What is the practical difference between the two?

like image 224
RobertL Avatar asked Sep 21 '09 13:09

RobertL


3 Answers

It doesn't matter. The return type is not part of a function's signature, as it does not participate in overload resolution. So when you attempt to perform an assignment, both declarations will match, regardless of whether you use the return type.

And since the entire point in these macros is that the functions will never get called, it doesn't matter that one returns void.

like image 89
jalf Avatar answered Sep 23 '22 07:09

jalf


I'd just like to mention that there is an alternative strategy for implementing an abstraction for disallowing copy and assignment of a class. The idea is to use inheritance instead of the preprocessor. I personally prefer this approach as I follow the rule of thumb that it is best to avoid using the preprocessor when at all possible.

boost::noncopyable is an example implementation. It is used as follows:

class A : noncopyable
{
    ...
};
like image 24
bartsimpson Avatar answered Sep 24 '22 07:09

bartsimpson


See Boost.Utility, specifically boost::noncopyable. It's not a macro but a base class with private copy and assignment. It prevents the compiler from generating implicit copy and assignment in derived classes.

edit: Sorry, this was not an answer to the original question. By the way, boost::noncopyable uses a const reference as return type for the assignment operator. I was under the impression that the type of the return value doesn't matter since it's not supposed to be used. Still, making the operator private doesn't prevent usage inside the class or friends in which case a non-usual return type (like void, a const reference, etc) might lead to compilation errors and catch additional bugs.

like image 39
sellibitze Avatar answered Sep 22 '22 07:09

sellibitze