Deleting copy constructors and copy assignment operators. Which of them are essential?
Asked Answered
S

2

31

I have a use case that my object must not be copied in any way. I have written an exaggerated complete list of copy constructor and copy assignment operator deletions below. There are so many of them that I can't make sure which ones to use, and sometimes this makes me paranoid. I don't have to write them all in my code, do I? So, in order to prevent object copying of any kind, which of them should I use?

        MyClass             (       MyClass &)  = delete;
        MyClass             (const  MyClass &)  = delete;
        MyClass             (       MyClass &&) = delete;
        MyClass             (const  MyClass &&) = delete;
        MyClass    operator=(       MyClass &)  = delete;
        MyClass    operator=(const  MyClass &)  = delete;
const   MyClass    operator=(       MyClass &)  = delete;
const   MyClass    operator=(const  MyClass &)  = delete;
        MyClass &  operator=(       MyClass &)  = delete;
        MyClass &  operator=(const  MyClass &)  = delete;
const   MyClass &  operator=(       MyClass &)  = delete;
const   MyClass &  operator=(const  MyClass &)  = delete;
        MyClass && operator=(       MyClass &)  = delete;
        MyClass && operator=(const  MyClass &)  = delete;
const   MyClass && operator=(       MyClass &)  = delete;
const   MyClass && operator=(const  MyClass &)  = delete;
        MyClass    operator=(       MyClass &&) = delete;
        MyClass    operator=(const  MyClass &&) = delete;
const   MyClass    operator=(       MyClass &&) = delete;
const   MyClass    operator=(const  MyClass &&) = delete;
        MyClass &  operator=(       MyClass &&) = delete;
        MyClass &  operator=(const  MyClass &&) = delete;
const   MyClass &  operator=(       MyClass &&) = delete;
const   MyClass &  operator=(const  MyClass &&) = delete;
        MyClass && operator=(       MyClass &&) = delete;
        MyClass && operator=(const  MyClass &&) = delete;
const   MyClass && operator=(       MyClass &&) = delete;
const   MyClass && operator=(const  MyClass &&) = delete;
Stavanger answered 18/11, 2015 at 9:51 Comment(3)
This seesm a little paranoid indeed :)Bruges
It also won't compile, because you can't overload on return value.Lacour
Besides, you forgot volatile ;-)Tyburn
A
68

You only need to mark a single copy constructor and copy assignment operator as delete. The presence of the copy versions will prevent the implicit-declaration of the move constructor and move assignment operator, and declaring one form of a copy special member function suppresses the implicit-declaration of other forms.

MyClass (const MyClass&) = delete;
MyClass& operator= (const MyClass&) = delete;

Note that post-C++11, implicit-definition of the assignment operator as defaulted is deprecated and it should instead be defined as deleted.

Attributive answered 18/11, 2015 at 9:58 Comment(3)
Just a very slight nitpick, and I might be wrong. Isn't the definition deprecated, not the declaration? They are always declared, but their definition is deleted. But I'm not a very good language lawyer.Galbraith
@Galbraith ah, you are correct, it should instead be implicitly-declared and defined as deleted, ([class.copy]/18), thanks.Attributive
What does your note mean in practice? Do you need to write something else?Croner
T
11

copy constructor

MyClass             (const  MyClass &)  = delete;

assignement operator

MyClass &  operator=(const  MyClass &)  = delete;

These are the only copy constructors ans copy assignement operators implicitly defined.

Toreador answered 18/11, 2015 at 9:55 Comment(2)
operator= isn't a constructor; and in general other constructors may be implicitly defined - but the presence of user-defined MyClass (const MyClass &) suppresses the other constructors.Jereme
Your "solution" is good but answer is actually wrong. The proper reasoning is that all assignment operators and constructors are implicitly defined unless, among other reasons, you define one by hand. Deletion counts as definition for this purpose.Galbraith

© 2022 - 2024 — McMap. All rights reserved.