Synopsis: | If you define or =delete any copy, move, or destructor function, define or =delete them all |
Language: | C++ |
Severity Level: | 2 |
Category: | Object Oriented Programming |
Description: |
The semantics of copy, move, and destruction are closely related, so if one needs to be declared, the odds are that others need consideration too. Declaring any copy/move/destructor function, even as =default or =delete, will suppress the implicit declaration of a move constructor and move assignment operator. Declaring a move constructor or move assignment operator, even as =default or =delete, will cause an implicitly generated copy constructor or implicitly generated copy assignment operator to be defined as deleted. So as soon as any of these are declared, the others should all be declared to avoid unwanted effects like turning all potential moves into more expensive copies, or making a class move-only. Example, bad: struct M2 { // bad: incomplete set of copy/move/destructor operations public: // ... // ... no copy or move operations ... ~M2() { delete[] rep; } private: pair<int, int>* rep; // zero-terminated set of pairs }; void use() { M2 x; M2 y; // ... x = y; // the default assignment // ... } Given that "special attention" was needed for the destructor (here, to deallocate), the likelihood that the implicitly-defined copy and move assignment operators will be correct is low (here, we would get double deletion). |
Literature References: |
C++ Core Guidelines |