Reputation: 87
http://en.cppreference.com/w/cpp/language/rule_of_three
I have begun with c++11 a couple of months ago and have watched the rule of five.
So.. I started putting copy constructor/copy assignment operator/move constructor/move assignment operator with default keyword on every class having virtual destructor.
because the rule told me that if you declare explicit destructor then your class doesn't have its implicit move constructor and move assignment operator anymore.
So I think gcc is going to complain to me that below class due to lack of move constructor and move assignment operator.
But It works well! What happend??
class Interface {
public:
virtual ~Interface() = default; // implicit destructor
};
class ImplA : public Interface {
public:
virtual ~ImplA() = default; // implicit destructor
};
ImplA first;
ImplA second(first); // copy constructor, OK. understood it.
ImplA third(std::move(first)); // move constructor, it's OK. Why?
second = first; // copy assignment, OK. understood it.
second = std::move(first); // move assignment, it's also OK. Why?
Upvotes: 2
Views: 230
Reputation: 172884
So I think gcc is going to complain to me that below class due to lack of move constructor and move assignment operator.
Because the operations required could be performed via copy constructor and copy assignment operator. Interface
still has copy constructor and copy assignment operator which are implcitly declared. And rvalues are always possible to be bound to const Interface&
.
More precisely, even without move constructor and move assignment operator provided, Interface
is still MoveConstructible,
A class does not have to implement a move constructor to satisfy this type requirement: a copy constructor that takes a
const T&
argument can bind rvalue expressions.
and MoveAssignable.
The type does not have to implement move assignment operator in order to satisfy this type requirement: a copy assignment operator that takes its parameter by value or as a
const Type&
, will bind to rvalue argument.
BTW: If you make the move constructor and move assignment operator delete explicitly then both copy and move operation would fail. Using with an rvalue expression the explicitly deleted overload will be selected and then fails. Using with an lvalue expression would fail too because copy constructor and copy assignment operator are implicitly declared as deleted because of the declaration of move constructor or move assignment operator.
Upvotes: 5