0

In C++ primer 5 ed. it is said:

"The fact that a base class needs a virtual destructor has an important indirect impact on the definition of base and derived classes: If a class defines a destructor—even if it uses = default to use the synthesized version—the compiler will not synthesize a move operator for that class (§13.6.2, p. 537)."

So for more understanding I've tried this:

class A
{
public:
    A(){cout << "A::A()\n";}
    virtual ~A(){cout << "A::~A()\n";}
    A& operator = (const A&) {cout << "A::=\n"; return *this;};
    A& operator = (A&&) = default;
};

int main()
{

    A a;
    A a2;
    a2 = std::move(a); // why copy-assignment operator is not called here. Normally a will be "moved" through copy-ctor (moving through working copy-ctor)


    std::cout << std::endl;
}
  • So according to the text above in the book class A has a virtual destructor thus the compiler won't synthesize a move-ctor/assignment operations But in main I've tried to move an object of type class A so normally move here uses copy-assignment instead of move-assignment but copy-assignment is not called here?!

  • So when a vairtual dtor causes a default operation be not synthesized? Thank you!

Maestro
  • 2,512
  • 9
  • 24
  • 1
    *even if it uses = default to use the synthesized version* - This applies to the destructor. I.e. if one defines `virtual ~A() = default;` – StoryTeller - Unslander Monica Jul 18 '20 at 22:41
  • 1
    The quote says the compiler won't **implicitly** declare a move assignment operator. But you explicitly asked for one to be defined. In any case, a move assignment is not implicitly declared when a user-defined copy assignment is provided; this is independent of whether the destructor is virtual. – Igor Tandetnik Jul 18 '20 at 22:43
  • 1
    Is it time for the [chart](https://stackoverflow.com/a/59616399/576911)? :-) – Howard Hinnant Jul 18 '20 at 22:49
  • @StoryTeller-UnslanderMonica: Still have the same confusion. Could you explain please. – Maestro Jul 18 '20 at 22:57
  • @IgorTandetnik: That means the normal rule applies: if a class defines a destructor (virtual or non-virtual) then the compiler won't synthesize a move operation for that class. Is this right? – Maestro Jul 18 '20 at 23:09
  • 1
    Yes. What the book is trying to say, I think, is that, if you need a virtual destructor, then you must define one - you can't simply omit it. And that has a side effect of suppressing move operations, so now those need to be defined, too (assuming the class needs them, of course). – Igor Tandetnik Jul 18 '20 at 23:13
  • @IgorTandetnik: Perfect! Thank you! I think you should post it as answer. – Maestro Jul 18 '20 at 23:14

1 Answers1

2

Your textbook is right, the compiler won't automatically synthesize a move operator. In the code sample you force the compiler to generate one by setting it to default, this can only fail if the move operator is implicitly deleted. Which is something else than it being implicitly declared.

Criteria for implicit deletion:

  • A has a non-static data member that is const
  • A has a non-static data member of a reference type
  • A has a non-static data member that cannot be move-assigned (has deleted, inaccessible, or ambiguous move assignment operator)
  • A has direct or virtual base class that cannot be move-assigned (has deleted, inaccessible, or ambiguous move assignment operator)
  • A has a non-static data member or a direct or virtual base without a move assignment operator that is not trivially copyable
  • A has a direct or indirect virtual base class

Criteria for implicit declaration:

  • there are no user-declared copy constructors;
  • there are no user-declared move constructors;
  • there are no user-declared copy assignment operators;
  • there are no user-declared destructors;
  • the implicitly-declared move assignment operator would not be defined as deleted

source