复制派生类中的构造和赋值运算符

Copy construct and assignment operator in the derived class

本文关键字:赋值运算符 派生 复制      更新时间:2023-10-16

我有一个继承另一个类(B类(的类(类A(。

class A: public B

B 类禁用了复制构造和赋值运算符(由于不允许复制(。

private:
 B(const B&);
 B& operator=(const B&);

我的问题是,我是否也应该在派生类中禁用复制构造和赋值运算符,或者如果我没有同时定义两者是否可以。

子类应该具有与其父类相同或更严格的[前提条件,后置条件和不变量]。这就是利斯科夫替代原则。因此,您不应该在派生类中重新启用复制构造等/任何内容,因为您将放松基类的合约。

如果你发现你需要这样做(或者真的想这样做(,那么这可能表明你需要重新考虑你的设计。

问题是,您是否应该重新启用它。 如果任何基或成员不可复制,则默认情况下您的类将不可复制。 通常,您不希望删除它,因为很难或不可能为其提供合理的语义。 但也有一些值得注意的例外:例如,如果基类是抽象的,您可能希望在派生类中启用复制构造函数(而不是赋值(以支持克隆。

不允许基类的复制构造函数和赋值运算符将导致派生类的复制构造函数和赋值运算符

也不可用:
class B {
public:
    B() { }
private:
    B(const B&);
    B& operator=(const B&);
};
class A : public B { };

在这种情况下,不需要显式禁止派生类使用这些,因为默认实现必须首先使用父级的实现。因此,如果您不尝试在代码中访问这些内容:

int main() {
    A a;
}

它将是完全有效的。但是,如果您尝试复制:

int main() {
    A a;
    A a2 = A(a);
}

编译器会抱怨类A试图访问B的私有成员(但是从语义上讲,第二种情况不应该发生(。