为什么当定义析构函数时,编译器不再添加默认的move函数和赋值函数
Why default move ctor and assignment are no more added by compiler when a destructor is defined?
我无法理解自动添加默认角色背后的原理。尤其让我感到尴尬的是,每次我只需要添加一个空的虚析构函数,仅此而已,我就丢失了move之类的东西,但添加它们时,我又丢失了copy和default之类的东西,所以我最后添加了所有这些代码块:
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
我确信有一个原因使我的类丑陋,让我想要一个邪恶的宏,我只是想知道它感觉更舒服。
看看这个。它解释了所谓的"五法则",这基本上是标准所要求的。
通常,在大多数情况下,编译器会为复制构造函数、复制赋值、move赋值和析构函数创建默认值。但是,如果程序员定义了其中的任何一个,那么编译器就会假设用户在这个类中封装了一些需要他/她的特殊功能的东西。析构函数。既然程序员知道他/她将需要一个析构函数,编译器将知道程序员知道发生了什么,而不会为其余部分创建默认值(因为,基于编译器所做的假设,默认值将是错误的,甚至可能导致不希望的行为)。
问题是您的类试图做两件独立的事情:提供多态接口(因此需要虚拟析构函数)和管理具体的数据成员(因此需要复制/移动操作)。一般来说,给每个类一个单独的职责是个好主意。
我将把虚析构函数和虚函数声明移到一个空的抽象基类中。然后,从它派生的任何具体类都可以自由地自动生成所有需要的东西。的例子:
#include <iostream>
struct Movable {
Movable() {}
Movable(Movable&&m) {std::cout << "Movingn";}
};
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
}
相关文章:
- 为什么不调用移动构造函数?(默认情况下只有构造器,没有别的)
- 无法将类对象转换为函数默认参数中的参考
- 如何使类的函数默认
- C++ 定义函数默认参数的正确方法
- 函数默认参数被忽略
- 构造函数默认公共和私有变量
- C++11 不生成特殊函数/默认构造函数
- 类模板构造函数默认参数
- 模板函数默认参数
- 重新声明时替换函数默认参数
- 模板函数默认参数和类型推断
- 构造函数默认参数
- C++模板构造函数默认参数
- 为什么内联函数默认情况下具有外部链接
- 在c++中设置构造函数默认值
- 虚函数默认参数和重载
- 指针对成员函数默认值出现与CRTP相关的编译器错误
- c++构造函数默认参数
- 名称空间中的两个对象将由不同的函数默认初始化,并由名称空间中的类使用
- C++中的函数默认参数