我有以下代码:
class C {
public:
C(int) {}
C(const C&) {}
C() {}
};
class D : public C {
public:
using C::C;
};
int main() {
C c;
D d_from_c(c); // does not compile, copy ctor is not inherited
D d_from_int(1); // compiles, C(int) is inherited
}
派生类应该继承除默认ctor之外的所有基数(解释为here)。但为什么复制ctor也不是继承的呢?这里不接受相关问题的论据。
代码使用g ++ 4.8.1编译。
答案 0 :(得分:15)
因为标准是这样说的。 [class.inhctor] / p3,强调我的:
对于继承的候选集中的每个非模板构造函数 构造函数除了没有参数的构造函数或者 具有单个参数的复制/移动构造函数,构造函数是 除非使用相同的构造函数特性隐式声明 有一个用户声明的构造函数,其中包含相同的签名 显示using声明的完整类或构造函数 将是该类的默认,复制或移动构造函数。
答案 1 :(得分:12)
派生类应继承除默认ctor
之外的所有基数
不,这不是真的,请参阅T.C.'s answer了解真实规则。
继承构造函数的目的是说“派生类型可以从与基类型相同的参数创建”,但这与基类的复制构造函数无关,因为复制构造函数不仅仅是说明如何从给定的参数创建类型的方式。
复制构造函数是特殊的,它用于复制相同类型的对象。
构造函数D(const C&)
不会用于复制相同类型的对象,因为C
与D
的类型不同。
答案 2 :(得分:1)
暂时,我们假设允许'复制构造函数继承'。 如果您的类结构完好无损,请考虑使用以下代码修改主要方法。
int main() {
C c;
D d;
D d_from_d(d);
D d_from_c(c); // does not compile, copy ctor is not inherited
D d_from_int(1); // compiles, C(int) is inherited
}
在D d_from_d(d)
中,作为普通的构造函数调用,将有两个复制构造函数调用。一个用于C :: C(const C&),另一个用于D的编译器生成的复制构造函数。在D中有源对象类型(在本例中为d),C的复制构造函数可以在编译器生成D的副本时复制d's C属性构造函数可以复制d's属性。
但在D d_from_c(c)
的情况下,C的复制构造函数没有问题,因为c的C属性可以由C的复制构造函数复制。但是编译器如何生成D的复制构造函数知道如何从C的对象复制'D'属性'。这是一个应该避免的冲突。
但是,如果你提供某种'奇怪的拷贝构造函数'(你可能也需要一个默认的构造函数),比如;
D(const C & c):C(c){}
然后,
致电D d_from_c(c);
已验证。因为,现在我们已经明确提供了匹配的'copy'构造函数。
因此,说'现在允许继承复制构造函数'是无效的。