C++ 为什么要删除基类的默认复制、移动和赋值?

C++ 为什么要删除基类的默认复制、移动和赋值?,c++,c++11,C++,C++11,为什么要删除基类的默认复制、移动和赋值 这是Stroustrup的书(第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 =

为什么要删除基类的默认复制、移动和赋值

这是Stroustrup的书(第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++中的实用性问题。 值类型是可互换的,特定实例是不相关的,它们应该是可复制和可分配的,并且像常规类型一样工作。示例可能包括特定日期、pi值、名称和颜色

引用类型表示一个事物的实例;具体的实例是相关的,它不仅仅是一个事物的描述。从语义上讲,允许复制这些内容是没有意义的。示例可能包括一个人、一个文件、一个线程

< > C++中多态性的类型是引用类型;它们必须通过引用(或指针)传递,以保持正确的行为。实际上,拷贝构造函数不是多态的;通过基引用进行复制可能会导致切片,从而改变行为,这是一种非常糟糕的副本表示。引入虚拟方法以允许多态类型的“克隆”是非常流行的

问题是建议基类应该是不可复制和不可分配的,但事实上,只有基类打算在适用的情况下以多态方式使用


在某些情况下,类被设计为继承而来,但它不是被设计为以多边形形式使用;例如,boost::noncopyable和CRTP类。在这种情况下,防止从它们派生的类的实例通过引用基来持有也是有意义的;通常通过使构造函数或析构函数中的一个或两个受保护或私有来降低其可见性。这些类不需要虚拟析构函数。

因此,作为一项规则,我应该始终删除我不打算实例化的基类的默认副本?@user311311311:是否可以实例化基类几乎没有关系。不允许复制也会阻止这种“通常基类是抽象的”请用证据支持这一说法。