According to “Rule Of Five” when I declare one of: copy or move operation or destructor I must write all of them, because the compiler doesn't generate them (some of them) for me. But if my class (A
) derives from an abstract class with a virtual destructor, does this mean that the destructor in class A
will be considered "user-defined"? As a consequence, will move semantics not work with objects of this class A
because compiler won't generate a move constructor for me?
struct Interface {
virtual void myFunction() = 0;
virtual ~Interface() {};
};
struct A : public Interface {
void myFunction() override {};
};
In [class.copy]:
If the definition of a class
X
does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only if
(9.1) — X does not have a user-declared copy constructor,
(9.2) — X does not have a user-declared copy assignment operator,
(9.3) — X does not have a user-declared move assignment operator, and
(9.4) — X does not have a user-declared destructor.
[ Note: When the move constructor is not implicitly declared or explicitly supplied, expressions that otherwise would have invoked the move constructor may instead invoke a copy constructor. —end note ]
Interface
does have a user-declared destructor, so Interface
's move constructor will not be implicitly declared as defaulted. But A
doesn't fit any of those bullet points - so it will have an implicit move constructor that is defaulted. A(A&& )
will just copy the Interface
part, as per the note. We can verify this by adding members to Interface
and A
:
#include <iostream>
template <char c>
struct Obj {
Obj() { std::cout << "default ctor" << c << "\n"; }
Obj(const Obj&) { std::cout << "copy ctor" << c << "\n"; }
Obj(Obj&&) { std::cout << "move ctor" << c << "\n"; }
};
struct Interface {
virtual void myFunction() = 0;
virtual ~Interface() {};
Obj<'I'> base;
};
struct A : public Interface {
void myFunction() override {};
Obj<'A'> derived;
};
int main() {
A a1; // default I, default A
std::cout << "---\n";
A a2(std::move(a1)); // copy I, move A
std::cout << "---\n";
A a3(a2); // copy I, copy A
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With