Most concise way to disable copying class in C++11 - c++

I have a problem dealing with deprecated since C++11 default generation of copy constructor and copy assignment operator when there is a user-defined destructor.
For most sufficiently simple classes default-generated constructors, operators and destructor are fine. Consider the following reasons to declare destructor:
Making trivial destructor virtual in base class:
// header
class Base1 { public: virtual ~Base1() = default; };
class Base2 { public: virtual ~Base2(); };
// source
Base2::~Base2() = default;
Would all 4 copy and move special methods be generated by compiler in these cases? If yes, then I think it is fine and there is no need to complicate Base1 or Base2.
Printing debug message in destructor:
// header
class D { public: ~D(); };
// source
D::~D() {
#ifdef DEBUG_THIS
std::cout << "D was destructed." << std::endl;
#endif
}
I believe that in this case copy constructor and assignment operator would be generated; but move constructor and assignment operator would not. I want to avoid using deprecated default-generating and disable copying of D. I also want to avoid flooding D with 4 deleted declarations. Is disabling only one copy constructor enough? Is it a good style?

With C++11, a clean way is to follow the pattern used in boost (see here)
You basically create a base class where copy constructor and copy assignment are deleted, and inherit it:
class non_copyable
{
protected:
non_copyable() = default;
~non_copyable() = default;
non_copyable(non_copyable const &) = delete;
void operator=(non_copyable const &x) = delete;
};
class MyClass: public non_copyable
{
...
}

Deleting the copy-constructor and copy-assignment operator is the simplest and clearest way to disable copying:
class X
{
X(X const &) = delete;
void operator=(X const &x) = delete;
};
I don't follow what you are talking about with virtual destructors in the question body . It sounds like you're asking for a way to make your code take up fewer characters of source code, but also be more cryptic to anybody looking at it.
If the list of deleted functions bothers you, you could hide them behind a macro, I guess.
#define NON_COPYABLE_NOR_MOVABLE(T) \
T(T const &) = delete; \
void operator=(T const &t) = delete; \
T(T &&) = delete;

Only copy constructor and copy assignment operator will be generated when destructor is explicitly defaulted. And even then their generation is deprecated. So, in order to have virtual destructor and all default methods, one should write the following:
struct Base
{
Base()=default;
virtual ~Base() = default;
Base(const Base&)=default;
Base& operator=(const Base&)=default;
Base(Base&&)=default;
Base& operator=(Base&&)=default;
};
I would definitely use a macro for more than one such Base class.
In case when destructor is defined by user, 2 special methods are still generated. There are the following ways to disable deprecated generating copy constructor and copy assignment operator:
delete move constructor OR move assignment operator (not quite self-explanatory but very short):
Base(Base&&)=delete; // shorter than deleting assignment operator
delete both copy constructor and copy assignment operator:
Base(const Base&)=delete;
Base& operator=(const Base&)=delete;
Note that you have to explicitly declare default constructor if you need it, e.g. Base()=default;.
Macro or inheriting special class can be used as well for this purpose but I personally prefer deleting move constructor to implementing my own macro or base class. When using Qt or boost, I would prefer Q_DISABLE_COPY(Base) and inheriting boost::noncopyable respectively, because they are already implemented, widely known and recognizable.
http://accu.org/index.php/journals/1896 - detailed explanation and rationale for these issues.

You can do it by this(which is used by Caffe: a fast open framework for deep learning):
// Disable the copy and assignment operator for a class.
#define DISABLE_COPY_AND_ASSIGN(classname) \
private:\
classname(const classname&);\
classname& operator=(const classname&)
Usage example:
class CNoCopyable{
public:
CNoCopyable(int i):m_d(i){}
private:
int m_d;
// add this line(pass class name)
DISABLE_COPY_AND_ASSIGN(CNoCopyable);
};

Related

Any disadvantage of inheriting from boost::noncopyable vs delete copy ctor and op? [duplicate]

To prevent copying a class, you can very easily declare a private copy constructor / assignment operators. But you can also inherit boost::noncopyable.
What are the advantages / disadvantages of using boost in this case?
I see no documentation benefit:
#include <boost/noncopyable.hpp>
struct A
: private boost::noncopyable
{
};
vs:
struct A
{
A(const A&) = delete;
A& operator=(const A&) = delete;
};
When you add move-only types, I even see the documentation as misleading. The following two examples are not copyable, though they are movable:
#include <boost/noncopyable.hpp>
struct A
: private boost::noncopyable
{
A(A&&) = default;
A& operator=(A&&) = default;
};
vs:
struct A
{
A(A&&) = default;
A& operator=(A&&) = default;
};
Under multiple inheritance, there can even be a space penalty:
#include <boost/noncopyable.hpp>
struct A
: private boost::noncopyable
{
};
struct B
: public A
{
B();
B(const B&);
B& operator=(const B&);
};
struct C
: public A
{
};
struct D
: public B,
public C,
private boost::noncopyable
{
};
#include <iostream>
int main()
{
std::cout << sizeof(D) << '\n';
}
For me this prints out:
3
But this, which I believe to have superior documentation:
struct A
{
A(const A&) = delete;
A& operator=(const A&) = delete;
};
struct B
: public A
{
B();
B(const B&);
B& operator=(const B&);
};
struct C
: public A
{
C(const C&) = delete;
C& operator=(const C&) = delete;
};
struct D
: public B,
public C
{
D(const D&) = delete;
D& operator=(const D&) = delete;
};
#include <iostream>
int main()
{
std::cout << sizeof(D) << '\n';
}
Outputs:
2
I find it much easier to declare my copy operations than to reason whether or not I'm deriving from boost::non_copyable multiple times and if that is going to cost me. Especially if I'm not the author of the complete inheritance hierarchy.
Summarizing what others have said:
Advantages of boost::noncopyable over private copy methods:
It is more explicit and descriptive in the intent. Using private copy functions is an idiom that takes longer to spot than noncopyable.
It is less code / less typing / less clutter / less room for error (the easiest would be accidentally providing an implementation).
It embeds meaning right in the type's metadata, similar to a C# attribute. You can now write a function which accepts only objects which are noncopyable.
It potentially catches errors earlier in the build process. The error will be presented at compile-time rather than link-time, in the case that the class itself or friends of the class are doing the erroneous copying.
(almost the same as #4) Prevents the class itself or friends of the class from calling the private copy methods.
Advantages of private copy methods over boost::noncopyable:
No boost dependency
It makes the intent explicit and clear, otherwise one has to see the definition of the class,and search for the declaration related to copy-semantic, and then look for the access-specifier in which it is declared, in order to determine whether the class is noncopyable or not. Other way to discover it by writing code that requires copy-semantic enabled and see the compilation error.
The intent of boost::noncopyable is clearer.
Boost::noncopyable prevents the classes methods from accidentally using the private copy constructor.
Less code with boost::noncopyable.
I can't understand why no one else seem to mention it, but:
With noncopyable you write the name of your class just once.
Without, fivefold duplication:
One A for 'class A', two to disable the assignment, and two to disable the copy constructor.
Quoting the documentation:
"The traditional way to deal with these is to declare a private copy constructor and copy assignment, and then document why this is done. But deriving from noncopyable is simpler and clearer, and doesn't require additional documentation."
http://www.boost.org/libs/utility/utility.htm#Class_noncopyable
One concrete advantage (beyond expressing your intent slightly more clearly) is that the error will be caught sooner, at the compile stage not the link stage, if a member or friend function tries to copy an object. The base-class constructor/assignment are not accessible anywhere, giving a compile error.
It also prevents you accidentally defining the functions (i.e. typing {} instead of ;), a small error which may well go unnoticed, but which would then allow members and friends to make invalid copies of the object.
A small disadvantage (GCC specific) is that, if you compile your program with g++ -Weffc++ and you have classes containing pointers, e.g.
class C : boost::noncopyable
{
public:
C() : p(nullptr) {}
private:
int *p;
};
GCC doesn't understand what's happening:
warning: 'class C' has pointer data members [-Weffc++]
warning: but does not override 'C(const S&)' [-Weffc++]
warning: or 'operator=(const C&)' [-Weffc++]
While it won't complain with:
#define DISALLOW_COPY_AND_ASSIGN(Class) \
Class(const Class &) = delete; \
Class &operator=(const Class &) = delete
class C
{
public:
C() : p(nullptr) {}
DISALLOW_COPY_AND_ASSIGN(C);
private:
int *p;
};
PS I know GCC's -Weffc++ has several issues. The code that checks for "problems" is pretty simplicistic, anyway... sometimes it helps.
The advantage is that you don't have to write a private copy constructor and a private copy operator yourself and it expresses clearly your intention without writing additional documentation.
I'd rather use boost::noncopyable than manually delete or privatize the copy constructor and assignment operator.
However, I almost never use either method, because:
If I am making a non-copyable object, there has to be a reason it is non-copyable. This reason, 99% of the time, is because I have members that can't be copied meaningfully. Chances are, such members would also be better suited as private implementation details. So I make most such classes like this:
struct Whatever {
Whatever();
~Whatever();
private:
struct Detail;
std::unique_ptr<Detail> detail;
};
So now, I have a private implementation struct, and since I've used std::unique_ptr, my top-level class is non-copyable for free. The link errors that come from this are understandable because they talk about how you can't copy a std::unique_ptr. To me, this is all the benefits of boost::noncopyable and a private implementation rolled into one.
The benefit with this pattern is later, if I decide that I did indeed want to make my objects of this class copyable, I can just add and implement a copy constructor and/or assignment operator without changing the class hierarchy.
The disavantage, according to Scott Meyers, the name is "non-natrual", if you do need to find a disavantage of it.

Does rule of three/five apply to inheritance and virtual destructors?

Let's assume we have a very basic class A:
class A {
public:
void SetName(const std::string& newName) {
m_name=newName;
}
void Print() const {
std::printf("A::Print(). Name: %s\n",m_name.c_str());
}
private:
std::string m_name;
};
We want to extend this class with class B so we add our virtual destructor, change a member to virtual and change private to protected for inh:
class A {
public:
virtual ~A() {}
void SetName(const std::string& newName) {
m_name=newName;
}
virtual void Print() const {
std::printf("A::Print(). Name: %s\n",m_name.c_str());
}
protected:
std::string m_name;
};
class B : public A {
public:
virtual void Print() const {
std::printf("B::Print(). Name: %s\n",m_name.c_str());
}
};
Now since we added a destructor in class A do we need to create a copy constructor and copy operator like so?
class A {
public:
virtual ~A() {}
A() = default;
A(const A& copyFrom){
*this = copyFrom;
}
virtual A& operator=(const A& copyFrom){
m_name=copyFrom.m_name;
return *this;
};
void SetName(const std::string& newName) {
m_name=newName;
}
virtual void Print() const {
std::printf("A::Print(). Name: %s\n",m_name.c_str());
}
protected:
std::string m_name;
};
To me this seems unnecessary as the default copy operator and copy constructor would do the same thing.
To be prepared for potential future evolution of the language, you should indeed explicitly default the copy/move constructors and assignment operators when you add a virtual destructor. That's because C++11, 12.8/7 makes implicit generation of copy constructors deprecated when the class has a user-declared destructor.
Fortunately, C++11's explicit defaulting makes their definition easy:
class A {
public:
virtual ~A() {}
A() = default;
A(const A& copyFrom) = default;
A& operator=(const A& copyFrom) = default;
A(A &&) = default;
A& operator=(A &&) = default;
void SetName(const std::string& newName) {
m_name=newName;
}
virtual void Print() const {
std::printf("A::Print(). Name: %s\n",m_name.c_str());
}
protected:
std::string m_name;
};
The rule of three applies to everything.
If your class is intended to be used as a polymorphic base, it's highly unlikely you will want to use its copy constructor because it slices. So you have to make a decision. That's what the rule of three is about: you can't choose to have a destructor without considering the copy special members.
Note that the rule of three doesn't say you're supposed to implement the copy constructor and copy assignment operator. You're supposed to deal with them somehow, because the default-generated one is highly likely not suitable if you have your own destructor (it slices!), but the way you deal with them doesn't have to be implementing them.
You should probably just forbid it since using polymorphic bases and value semantics tend to mix like water and oil.
I guess you could maybe make it protected so derived classes can call it for their own copies, though I still consider that a questionable choice.
Additionally, since C++11 the generation of copy special members is deprecated when a destructor is user-declared. That means that if you want your code to be forward-compatible, even if you want the default copy constructor behaviour (a questionable choice), you will want to make that explicit. You can use = default for that.
If the destructor doesn't do anything, then there's (usually) no need for the copy/move operations to do anything other than the default. There's certainly no need to write versions that do what the defaults would, just to satisfy an over-simplification of the rule. All that does is increase the complexity of the code and the scope for error.
However, if you do declare a virtual destructor, indicating that the class is intended to be a polymorphic base class, you might consider deleting the copy/move operations to prevent slicing.
This article gives a useful wording for the rule, including
If a class has a nonempty destructor, it almost always needs a copy constructor and an assignment operator.

C++ Inheritance of copy, move, swap, assignment and destructor? Which do I need

Let's say that I have two classes
Base manages some memory. It has working move, swap, assignment and destructor.
Derived does not add anything new that need need to be managed (no new memory allocations).
class Base
{
public:
Base();
Base(const Base& other);
friend void swap(Base& a, Base& b);
Base(Base&& other);
protected:
int** some2Darray;
int w, h;
};
class Derived : public Base
{
public:
Derived();
//...?
};
Do I need to implement all those functions in derived class for it to be good? How to reuse those functions from base class? I don't need to manage any more memory in this class.
How those function would look if I added member to Derived class? Should I totally rewrite all those functions or is there some way to use for example "copy" base class and just copy that one added member additionally in copy constructor?
You can inherit (edit: yeah, well this is not true inheritance, maybe this shall be noted explicitly) constructors since c++11. Via
class Derived : public Base
{
public:
Derived();
using Base::Base; // <-- this will import constructors
};
But this will not take care of any extras!
However, you do not need to copy code. You can just call parent functions.
E.g:
class Derived : public Base
{
int extra;
public:
Derived() : Base(), extra(42){};
Derived(const Derived& other) : Base(other) {extra = other.extra;};
void copy(const Derived& other);
friend void swap(Derived& a, Derived& b);
};
void Derived::copy(const Derived& other){
Base::copy(other);
extra = other.extra;
}
Also don't forget about virtual destructor.
EDIT:
For swap I would just cast derived instances to their bases to make compiler use the swap defined for parent type. Then swap extra stuff.
void swap(Derived& a, Derived& b){
swap(static_cast<Base&>(a), static_cast<Base&>(b));
swap(a.extra, b.extra);
}
First of all: constructors, assignment operators and destructors are not inherited (*). Instead, they may, in some circumstances, be synthesized automatically for you by the compiler.
So, when do you need to write them ? Only when the default generated version does not correspond to your needs:
the accessibility is not what you wish (it's always public)
the method should be deleted
the default behavior is incorrect (shallow copy, for example)
the compiler cannot synthesize the method for you
Regarding the latter two points:
the Rule of Three states that if you write any one of the Copy Constructor, Copy Assignment Operator or Destructor; you should provide the other two as well
in C++11, if you write any of those 3 special methods, then the Move Constructor and Move Assignment Operator are not synthesized automatically
in C++11, if you write either a Move Constructor or Move Assignment Operator, then none of those 3 special methods is synthesized automatically either
(*) The C++11 feature called inheriting constructors is ill-named, it is more delegating than inheriting.
That being said, if Derived does not have any tricky attribute, then you can probably avoid writing those members. If you still wish to write them (to avoid inlining for example), you should be able to use the = default syntax:
// Derived.h
class Derived: public Base {
public:
Derived(Derived const&) = default;
Derived& operator(Derived const&);
};
// Derived.cpp
Derived& Derived::operator=(Derived const&) = default;
I'm not sure about the move operator, but you don't have to implement copy ctor, destructor and copy operator as the standard functions will automatically call the corresponding functions from all base classes.
EDIT: see also How to use base class's constructors and assignment operator in C++?

Not copyable object and exception in copy constructor and operator=

I'd like to make object of class not copyable so I put copy constructor and operator= in private section. However one class is friend of this class so it has access to private methods. Is it good idea to put throw exception in copy constructor and operator= to be sure that object will not be copied?
One approach to make it not copyable is just to declare the copy constructor, but don't implement it at all. That will force a linker error at compile time if anyone tries to use it.
class foo
{
private:
foo(const foo&); // not defined
foo& operator=(const foo&); // not defined
};
#Mysticial have answered this question which is usually done in C++03. But in C++11, you can do this, more nicely:
class foo
{
private:
foo(const foo&) = delete;
foo& operator=(const foo&) = delete;
};
The =delete conveys the message that foo doesn't support copy-semantic, as it has been disabled by explicitly marking it with delete. I've explained this in detail here:
Is there a way to disable constructor synthesizing on a class?

Can I prevent object assignment?

I want to ensure that the following type of call is illegal:
MyClass me;
MyClass you;
me = you; // how to make this illegal?
Is it possible?
Declare the assignment operator private:
class A {
private:
void operator=(const A&);
...
};
but don't provide an implementation - you will get a compile or link-time error if you try to perform an assignment to A.
I prefer to use a macro to do this. This also prevents copying, by making the copy constructor private too:
#define CANNOT_COPY( class ) \
private: \
class(const class&); \
void operator=(const class &) \
I can then say things like:
class A {
CANNOT_COPY( A );
...
};
which is easy to read and easy to search for.
declare the assignment operator as private.
Yes - define a private assignment operator (operator=) or derive from the handy boost::noncopyable class.
As of C++11, my understanding is that the preferred solution is to use the '= delete' construct:
class MyClass {
MyClass (const MyClass&) = delete; // Disable copy constructor
MyClass& operator=(const MyClass&) = delete; // Disable assignment
...
}
Then
MyClass me;
MyClass you;
me = you; // won't compile
Use const.
MyClass const me;
MyClass you;
me = you; // compilation error
I use to derive my noncopyable classes from a common noncopyable class. If not using boost, I usually use this shortcut:
class NonCopyable
{
protected:
/**
* Protected default constructor
*/
NonCopyable() {}
/**
* Protected destructor
*/
~NonCopyable() {}
private:
/**
* Private copy constructor
*/
NonCopyable( const NonCopyable& );
/**
* Private assignment operator
*/
const NonCopyable& operator=( const NonCopyable& );
};
Note that neither the copy constructor nor the assignment operators have an implementation.
The other answers here are all correct. However, it is important to note that you are only prohibiting the specific code you mentioned. Someone can still come along and make a duplicate of your class by using memcpy or other strategies.