显式默认的析构函数禁用 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
获得预期输出的原因,其中您通过显式 = default
ing 特殊成员函数来覆盖编译器的默认操作。 compiler-generated 移动构造函数对可移动基 class 类型做正确的事情,因此请遵循 rule of five 和 = default
D
.[=18 的特殊成员函数=]
看看 this answer 中的 table。放在枕头底下很有参考价值
我遇到了 运行 一个问题,即当超类的子类具有显式默认的析构函数时,超类的移动构造函数未被正确调用。当隐式默认析构函数(在超类定义中根本没有提供)时,确实会调用移动构造函数。
我知道 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
获得预期输出的原因,其中您通过显式 = default
ing 特殊成员函数来覆盖编译器的默认操作。 compiler-generated 移动构造函数对可移动基 class 类型做正确的事情,因此请遵循 rule of five 和 = default
D
.[=18 的特殊成员函数=]
看看 this answer 中的 table。放在枕头底下很有参考价值