指定派生类的析构函数时,std :: move不起作用

Sea*_*ene 19 c++

我试图将一个实例移动到另一个实例,如下所示:

#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);
}
Run Code Online (Sandbox Code Playgroud)

这是输出:

copy student
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,std::move没有工作,student被复制而不是被移动,但是,如果我删除了undergraduate析构函数,即以下行:

~undergraduate() override = default; // removing this line will make std::move work
Run Code Online (Sandbox Code Playgroud)

输出将变为move student,这意味着std::move有效.为什么?为什么在std::move指定派生类的析构函数时不起作用?

Vit*_*meo 39

指定类的析构函数会禁止自动生成移动构造函数并移动赋值.您可以使用= 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;
};
Run Code Online (Sandbox Code Playgroud)

Howard Hinnant为他的"你想要了解的关于移动语义的东西(以及其他一些)"创建了一个很好的表格"演示:

在此输入图像描述

  • 更容易记住的规则:`= default`或`= delete`或在触摸任何一个时实现5个特殊成员函数. (8认同)
  • 来自主持人的幻灯片:https://accu.org/content/conf2014/Howard_Hinnant_Accu_2014.pdf (7认同)
  • 谢谢你的桌子!介意我是否积极保存和使用? (3认同)