为什么要删除基类的默认复制并移动ctor和赋值
Why delete default copy and move ctor and assignment for base classes?
为什么要删除基类的默认复制并移动ctor和赋值?
这是来自斯特劳斯特鲁普的书(第4版c++)。
通常基类是抽象的,所以你为什么要担心呢,当你甚至不能实例化它们的时候。
您试图避免的情况:
class A
{
};
class B : public A
{
};
class C : public A
{
int foo;
};
int main(int argc, char** argv)
{
A* c_ptr = new C();
A* b_ptr = new B();
*b_ptr = *c_ptr;//unless you explictly dissalow this, it can be done!
}
答案是双重的;一个是语义问题,另一个是C++中的实用性问题。
值类型是可互换的,特定的实例是不相关的,它们应该是可复制的和可赋值的,并且表现得像常规类型。示例可能包括特定日期、圆周率值、名称和颜色。
引用类型表示事物的实例;具体的例子是相关的,它不仅仅是对一件事的描述。从语义上讲,允许复制这些内容是没有意义的。示例可能包括一个人、一个文件、一个线程。
C++中多态的类型是引用类型;它们必须通过引用(或指针)传递,以保持正确的行为。在实践中,复制构造函数不是多态的;通过基引用进行复制可能会导致切片,从而导致行为的改变,这是对副本的一种非常糟糕的表示。引入一种虚拟方法来允许多态类型的"克隆"是非常流行的。
这个问题建议基类应该是不可复制和不可赋值的,但事实上,只有基类才打算在这种情况下以多态方式使用。
在某些情况下,类被设计为继承自,但它并不是被设计为循环使用的;例如boost::non-copyable和CRTP类。在这种情况下,防止从它们派生的类的实例通过引用基来持有也是有意义的;通常是通过将构造函数或析构函数中的一个或两个设置为受保护或私有来降低它们的可见性。这些类不需要虚拟析构函数。
相关文章:
- 给定一个右值,为什么移动ctor比常量复制ctor更匹配
- std::任何只用于移动的模板,其中副本ctor内的static_assert等于编译错误,但为什么
- 为什么当我不移动任何东西时,clang 会抱怨删除移动 ctor?
- 相同指令的输出不同 - 移动并复制CTOR
- 复制ctor被称为而不是移动ctor-可以编译器发出警告
- 为什么移动 ctor 比复制 ctor 慢?
- 当使用三元运算符并删除移动/复制CTOR时,Visual Studio不执行RVO
- 自 C++17 以来,复制 elision 不需要存在和访问复制或移动 CTOR
- 转换和移动 ctor 导致对 Clang 和 GCC 4.9.2 的模棱两可的要求
- 析构函数是移动ctor/赋值的RHS上唯一调用过的东西吗
- 移动类的数组成员所需的ctor
- 移动具有常量数据成员或引用成员的类的ctor
- 用于包装unique_ptr的模板化移动 ctor
- 为什么要删除基类的默认复制并移动ctor和赋值
- 移动 ctor 是否在所有情况下都有效
- 当使用类型为"类&&"的变量作为参数时,为什么调用复制 ctor 而不是移动 ctor
- C++11:调用移动 ctor/operator= 时
- 使用移动 CTOR 的 constexpr 对象的 constexpr 数组
- 显式移动 ctor 是否消除了隐式复制 ctor
- 代码调用复制 ctor 通常必须调用移动 ctor