我有一个继承另一个类(B类)的类(A类)。
class A: public B
B类禁用复制构造和赋值运算符(由于不允许复制)。
private:
B(const B&);
B& operator=(const B&);
我的问题是,我是否也应该在派生类中禁用复制构造和赋值运算符,或者如果我没有定义它们也没关系。
答案 0 :(得分:3)
子类应该具有与其父类相同或更严格的[前置条件,后置条件和不变量]。这是Liskov Substitution Principle。因此,您不应该在派生类中重新启用复制构造等等,因为您将放松基类的合同。
如果您发现需要这样做(或者真的想这样做),那么可能表明您需要重新考虑您的设计。
答案 1 :(得分:1)
问题是,如果你重新启用它。如果任何基础或成员是不可复制的,则默认情况下您的类将是不可复制的。通常,您不希望将其删除,因为很难或不可能给它合理的语义。但是有一些值得注意的例外:例如,如果基类是抽象的,您可能希望在派生类中启用复制构造函数(但不是赋值)以支持克隆。
答案 2 :(得分:0)
禁止复制构造函数和基类的赋值运算符将导致派生类的复制构造函数和赋值运算符也不可用:
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
的私有成员(但在语义上不应该发生第二种情况)。