C++应该重写派生类中的复制构造函数吗
C++ Should I overwrite copy constructor in derived class
我有一个带有自定义复制构造函数的基类,它负责处理分配的内存。我也从那个基地开始上课。该派生类没有对内存做任何其他操作。
复制构造函数在dervied类中应该是什么样子?覆盖交换、移动和分配如何?
除了swap
,您不应该做任何其他事情。在这方面,基类就像一个数据成员,编译器生成的复制构造函数和赋值(以及移动(如果适用))包括它
swap
不同,因为没有编译器生成的swap
,只有命名空间std
中的默认实现,然后是程序员为用户定义的类型定义的任何专门化或ADL重载。
因此,如果已经有一个函数看起来像:
namespace foo {
void swap(Base &lhs, Base &rhs) {
lhs.swap(rhs); // or maybe the gory details are in this function
}
}
你什么都不做,有些用户称之为:
foo::swap(derived1, derived2);
然后基础部件将被交换,而派生部件不会,这非常糟糕。
用户不应该这样调用swap,但你知道用户是什么样的。如果Base
和Derived
在同一个命名空间中,并且他们只是假设它们都能工作,那么用户可能会觉得这特别有吸引力。因此,如果您认为您的用户(或您自己的代码库)在调用swap
的方式上没有原则,您可能需要确保Derived
有过载以阻止它们。
用户应调用swap
,如:
using std::swap;
swap(base1, base2);
swap(derived1, derived2);
当与Base
一起使用时,它将调用foo::swap
,而当与Derived
一起调用时,它会调用std::swap
。std::swap<Derived>
可能效率低下(如果Base
为了效率而实现了交换,那么Derived
也应该如此)。因此,出于这个原因,您可能也想为Derived
实现swap
,但速度慢并没有错那么糟糕。
也就是说,你在问动作。如果CCD_ 19是可有效移动的,那么CCD_。也许它可以改进,也许不能,但它应该是边缘的,因为三步很难被击败。
您和用户还应该意识到,swap
不能很好地处理多态性(因为通常情况下,两个对象必须具有相同的完整类型才能进行交换),并且为基类实现它可能会带来麻烦。
Derived d1, d2;
Base &b1 = &d1, &b2 = d2;
swap(b1, d2); // swaps just the base part
swap(b1, b2); // swaps just the base part
因此,首先,用户需要知道不要这样调用swap。其次,您可能需要考虑带有swap
的Base
作为基类是否真的设计良好。
有一个所谓的五规则(以前的三规则),它说如果你有用户定义的任何一个:
- 复制构造函数
- 移动构造函数
- 析构函数
- 复制分配运算符
- 移动分配运算符
您可能还希望用户定义其他四个。
另一方面,有一条零规则:您可以使用自动处理这些事情的资源对象(RAII),而不是定义这五个特殊的成员函数。
这样的对象是数据成员还是某个类C
的基类(子对象)并不重要:隐式声明的&编译器提供的C
的已定义特殊成员函数将调用该资源对象的特殊成员函数,这很可能就足够了。
提示:对于特定的示例,可以给出更精确的答案
不能"覆盖"构造函数。它不是C++词汇表中的一个术语。您可以覆盖函数,但前提是它是虚拟的。
通常,您不应该在任何正确编写的基类的子类的构造函数中做任何特殊的事情。让每一代人都照顾好自己。
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 当从函数参数中的临时值调用复制构造函数时
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- 复制构造函数、赋值运算符C++
- std::ofstream 作为类成员删除复制构造函数?
- 复制构造函数C++无法正确复制指针
- 关于复制构造函数的一个棘手问题
- 为什么调用复制构造函数而不是移动构造函数?
- 填充上编译器生成的复制构造函数之间的不一致
- C++ 对象指针数组的复制构造函数
- C++ 基本 CTOR 说明 - 为什么不调用赋值/复制构造函数
- 防止在复制构造函数中隐式调用基构造函数
- 为用户定义的类正确调用复制构造函数/赋值运算符
- 具有已删除移动和复制构造函数的类的就地构造
- 复制构造函数隐式转换问题
- 复制构造函数中的递归调用