dimanche 7 mars 2021

Deriving from an abstract base with a user-declared dtor and move-support

A user-declared dtor prevents the autogeneration of the move-ctor/-assignment-operator, but will the autogeneration only be prevented in the class where the dtor has been defined or will the autogeneration be prevented in all derived classes too? I am asking this, because I am using many pure virtual classes which all provide a user-declared dtor. Do I have to upgrade now all this classes to get move-support or will it work still out-of-the-box?

Here is an example of how my scenarios currently looks like:

struct BigData {};

struct BaseA
{
    virtual void func() = 0;
    virtual ~BaseA() = default;
};

struct A : public BaseA
{
    BigData _data;
    void func() override {}
};

Now, which of the following variants I have to use to be sure, that moving will be used like in the following example?

A a;
std::vector< A > va;
va.push_back( std::move( a ) ); //Should really use move instead of copy

Variant 1: Upgrade base class only

struct BaseA
{
    virtual void func() = 0;
    virtual ~BaseA() = default;

    BaseA() = default;
    BaseA(BaseA&&) = default;
    BaseA& operator=(BaseA&&) = default;
    BaseA(const BaseA&) = default;
    BaseA& operator=(const BaseA&) = default;
};

struct A : public BaseA
{
    BigData _data;
    void func() override {}
};

Variant 2: Upgrade derived class only

struct BaseA
{
    virtual void func() = 0;
    virtual ~BaseA() = default;
};

struct A : public BaseA
{
    BigData _data;
    void func() override {}
    A() = default;
    A(A&&) = default;
    A& operator=(A&&) = default;
    A(const A&) = default;
    A& operator=(const A&) = default;
};

Variant 3: Upgrade base class and derived class

struct BaseA
{
    virtual void func() = 0;
    virtual ~BaseA() = default;

    BaseA() = default;
    BaseA(BaseA&&) = default;
    BaseA& operator=(BaseA&&) = default;
    BaseA(const BaseA&) = default;
    BaseA& operator=(const BaseA&) = default;
};

struct A : public BaseA
{
    BigData _data;
    void func() override {}
    A() = default;
    A(A&&) = default;
    A& operator=(A&&) = default;
    A(const A&) = default;
    A& operator=(const A&) = default;
};

Variant 4: Nothing to do

Aucun commentaire:

Enregistrer un commentaire