Home > Enterprise >  Does the destructor of the baseclass prevent creation of move constructors in subclasses?
Does the destructor of the baseclass prevent creation of move constructors in subclasses?

Time:05-04

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

Try it online!

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.

  • Related