As per this post, which says that[emphasise mine]:
The move assignment operator is auto-generated if there is no user-declared copy constructor, copy assignment operator or destructor, and if the generated move assignment operator is valid (e.g. if it wouldn't need to assign constant members) (§12.8/21).
Does an inherited destructor count? I mean, say I've got a base class with an empty virtual destructor. Does it prevent creation of move constructors in subclasses?
CodePudding user response:
The compiler will generate the move constructors for you:
#include <iostream>
#include <memory>
#include <utility>
struct Foo {
virtual ~Foo() {}
};
struct Bar : public Foo {
Bar() : pi(new int(5)) {};
std::unique_ptr<int> pi;
};
int main()
{
Bar b;
std::cout << b.pi.get() << std::endl;
Bar c = std::move(b);
std::cout << b.pi.get() << std::endl;
std::cout << c.pi.get() << std::endl;
}
which (on a given run), output:
0x1b65e70
0
0x1b65e70
If the compiler had not generated the move constructor, c
could not have been constructed (since by using std::unique_ptr
as a member, implicit copy is not allowed), and clearly the ownership over the pointer was transferred properly. The code was compiled under GCC with warnings maxed out in -std=c 17
mode, with no issues.
CodePudding user response:
You can tell if a member function is user-declared by looking at the class definition. If you see the function, then it is user-declared.
For example:
class Derived : public Base {
~Derived() = default; // <-- see this? user-declared destructor
};
In contrast to:
class Derived : public Base {
// <-- see a destructor here? No. So not a user-declared destructor
};
The compiler generates the same destructor body in both cases, but the former example has a user-declared destructor, while the latter has an auto-generated destructor. The user-declared destructor is compiler-generated in this case, but it is generated at the user's request, so it is not auto-generated.
For "user-declared", it does not matter what's going on in the base class. If you see the destructor listed, as in the first example, then the compiler will not auto-generate move assignment or move construction.