Why delete default copy and move ctor and assignment for base classes?
This is from Stroustrup's book (4-th edition c++).
Usually base classes are abstract so why would you worry about that at all, when you can't even instantiate them.
Why delete default copy and move ctor and assignment for base classes?
This is from Stroustrup's book (4-th edition c++).
Usually base classes are abstract so why would you worry about that at all, when you can't even instantiate them.
The situation you are trying to avoid:
class A
{
};
class B : public A
{
};
class C : public A
{
int foo;
};
int main(int argc, char** argv)
{
A* c_ptr = new C();
A* b_ptr = new B();
*b_ptr = *c_ptr;//unless you explictly dissalow this, it can be done!
}
The answer is twofold; one is a matter of semantics and the other is a matter of practicality in C++.
Value types are interchangeable, a specific instance is not relevant, they should be copyable and assignable and act like regular types. Examples might include a specific date, the value of pi, a name, a colour.
Reference types represent an instance of a thing; the specific instance is relevant, it's not just a description of a thing. Semantically, it doesn't make sense to allow copying of these. Examples might include a person, a file, a thread.
Types that are polymorphic in C++ are reference types; they must be passed by reference (or pointer) in order to maintain the correct behaviour. In practice, copy constructors are not polymorphic; copying through a base reference can lead to slicing, and thus a change in behaviour, which is a very poor representation of a copy. It is quite popular to introduce a virtual method to allow "cloning" of the polymorphic type.
The question suggested base classes should be non-copyable and non-assignable, but in fact, it is only base classes that are intended to be used polymorphically where this applies.
There are occasions where a class is designed to be inherited from, but it is not designed to be used poymorphically; for example, boost::noncopyable and CRTP classes. In this case it also makes sense to prevent instances of classes derived from them to be held by reference to the base; usually by reducing the visibility of the constructor or destructor by making one or both of them protected or private. These classes do not require a virtual destructor.