为什么默认移动ctor并且在定义析构函数时编译器不再添加赋值?

时间:2014-07-24 14:58:02

标签: c++ c++11 constructor default

我无法理解自动添加默认ctors背后的基本原理。特别是我觉得非常尴尬,每次我只需要添加一个空的虚拟析构函数,仅此而已,我放松了移动的东西,但添加它们我松散副本和默认的东西,所以我最终添加所有这些代码:

virtual ~SomeClass(){}           // you are the guilty!
//virtual ~SomeClass() = default // would be the same

SomeClass(SomeClass&&) = default;                 // no more auto-added
SomeClass& operator=(SomeClass&&) = default;      // no more auto-added
SomeClass(const SomeClass&) = default;            // but with the moves defined,
SomeClass& operator=(const SomeClass&) = default; // I'm now missing the copy
SomeClass(){}                                     // and the default as well

我确信有理由让我的课程变得丑陋,让我想要一个邪恶的宏观,我只是想让它感觉更舒服。

2 个答案:

答案 0 :(得分:1)

看看this。它解释了一个称为五的规则,这基本上是标准要求的。

通常,对于大多数情况,编译器会为复制构造函数,复制赋值,移动赋值和析构函数创建默认值。但是,如果程序员定义了这些中的任何一个,那么编译器假定用户已经在这个类中封装了需要他/她特殊的东西,让我们说。析构函数。既然程序员知道他/她将需要一个析构函数,编译器就会知道程序员知道发生了什么,而不是为其余的创建默认值(因为,基于编译器的假设) make,默认值会出错,甚至可能导致不良行为。)

答案 1 :(得分:0)

问题是你的类正在尝试做两件事:提供多态接口(因此需要虚拟析构函数)和管理具体数据成员(因此需要复制/移动操作)。为每个班级承担一项责任通常是一个好主意。

我将虚拟析构函数和任何虚函数声明移动到一个空的抽象基类。那么任何具体的类都可以自由地生成所有需要的东西。

示例:

#include <iostream>

struct Movable {
    Movable() {}
    Movable(Movable&&m) {std::cout << "Moving\n";}
};

struct SomeInterface {
    virtual ~SomeInterface() {}

    // no data members, so no need for any other special member functions
};

struct SomeClass : SomeInterface {
    Movable stuff;

    // no user-declared special functions, so all are auto-generated
};

int main() {
    SomeClass c;
    SomeClass c2(std::move(c));  // uses the auto-generated move constructor
}