我有一个类(A 类),它继承了另一个类(B 类)。
class A: public B
B 类禁用复制构造和赋值运算符(由于不允许复制)。
private:
B(const B&);
B& operator=(const B&);
我的问题是,我是否也应该在派生类中禁用复制构造和赋值运算符,或者如果我没有同时定义两者是否可以。
我有一个类(A 类),它继承了另一个类(B 类)。
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
(但是从语义上讲,第二种情况不应该发生)。