C++ 标准::移动不';当派生类';已指定析构函数
我试图将一个实例移动到另一个实例,如下所示:C++ 标准::移动不';当派生类';已指定析构函数,c++,C++,我试图将一个实例移动到另一个实例,如下所示: #include <iostream> class student { public: student() = default; student(const student& student) { std::cout << "copy student" << std::endl; } student(student&& student) {
#include <iostream>
class student {
public:
student() = default;
student(const student& student) {
std::cout << "copy student" << std::endl;
}
student(student&& student) {
std::cout << "move student" << std::endl;
}
virtual ~student() = default;
};
class undergraduate: public student {
public:
undergraduate(): student() {}
~undergraduate() override = default; // removing this line will make std::move work
};
int main() {
undergraduate student;
undergraduate student1 = std::move(student);
}
如您所见,std::move
不起作用,student
被复制而不是移动,但是,如果我删除本科生的析构函数,即以下行:
~undergraduate() override = default; // removing this line will make std::move work
输出将变成move student
,这意味着std::move
可以工作。为什么?指定派生类的析构函数时,std::move
为什么不起作用?指定类的析构函数会禁止自动生成移动构造函数和移动赋值。您可以使用=default
还原它们:
class undergraduate: public student {
public:
undergraduate(): student() {}
~undergraduate() override = default;
undergraduate(const undergraduate&) = default;
undergraduate& operator=(const undergraduate&) = default;
undergraduate(undergraduate&&) = default;
undergraduate& operator=(undergraduate&&) = default;
};
Howard Hinnant创建了一个优秀的表格,提供了您想要了解的关于移动语义的所有信息(以及一些)“演示:
谢谢你的表格!介意我集中保存和使用吗?@YSC:我不相信这张表格,它是由Howard Hinnant制作的。主持人的幻灯片:更容易记住的规则:=default
或=delete
,或者在你触摸其中任何一个时实现5个特殊成员函数。你编写了移动构造函数,但没有一个匹配的移动赋值运算符。为什么不?std::move
总是起作用。在“不能起作用”中,这是一个伪装。问题是,为什么不调用移动构造函数?下面回答了这个问题。@JesperJuhl,因为这里使用的是移动构造函数而不是移动赋值。在初始化对象时调用移动构造函数,如 T a=std::move(b);
或T a(std::move(b));
,查看更多详细信息。
class undergraduate: public student {
public:
undergraduate(): student() {}
~undergraduate() override = default;
undergraduate(const undergraduate&) = default;
undergraduate& operator=(const undergraduate&) = default;
undergraduate(undergraduate&&) = default;
undergraduate& operator=(undergraduate&&) = default;
};