显式默认的析构函数禁用 class 中的默认移动构造函数

Explicitly defaulted destructor disables default move constructor in a class

我遇到了 运行 一个问题,即当超类的子类具有显式默认的析构函数时,超类的移动构造函数未被正确调用。当隐式默认析构函数(在超类定义中根本没有提供)时,确实会调用移动构造函数。

我知道 constraints that the compilers should apply to default move constructors. Yet, I have been by all means sure that the compiler should not discriminate between explicitly/implicitly defaulted destructors (or constructors as well) when applying these rules. In other words, explicitly defaulted destructor should not be treated as user-defined one (in contrast to an 用户定义的析构函数)。

仅使用 MSVC 2019 进行测试。

我或 MSVC 就在这里吗?


#include <iostream>

class A {
public:
    A() = default;
    A(const A&) { std::cout << "Auch, they'r making copy of me(?!)" << std::endl; }
    A(A&&) { std::cout << "I am moving :)" << std::endl; }

    ~A() = default;
};

class B : public A {
public:

};

class C : public A {
public:

    C() = default;

};

class D : public A {
public:

    ~D() = default;

};

class E : public A {
public:

    E() = default;
    E(const E&) = default;
    E(E&&) = default;
    ~E() = default;

};

int main()
{

    std::cout << "\n---- A ----\n" << std::endl;

    A a;
    A a2(std::move(a));

    std::cout << "\n---- B ----\n" << std::endl;

    B b;
    B b2(std::move(b));

    std::cout << "\n---- C ----\n" << std::endl;

    C c;
    C c2(std::move(c));

    std::cout << "\n---- D ----\n" << std::endl;

    D d;
    D d2(std::move(d));

    std::cout << "\n---- E ----\n" << std::endl;

    E e;
    E e2(std::move(e));

}


预期:在所有情况下显示 "I am moving :)"

ACTUAL:在 D

的情况下显示 "Auch, they'r making copy of me(?!)"

当您在 D 中声明默认析构函数时,您禁用 compiler-generated 移动构造函数和移动赋值运算符 D (!),not 基础 class 版本。这就是为什么您使用 E 获得预期输出的原因,其中您通过显式 = defaulting 特殊成员函数来覆盖编译器的默认操作。 compiler-generated 移动构造函数对可移动基 class 类型做正确的事情,因此请遵循 rule of five= default D.[=18 的特殊成员函数=]

看看 this answer 中的 table。放在枕头底下很有参考价值