我知道这个问题已被多次提出,我已经阅读了不同的答案,以及ISO标准的某些部分。
但是,我仍然需要一些澄清关于C ++标准所期望的确切行为。
假设:
class A
{
public:
A( void ) {}
A( const A & a ) {}
};
class B: public A
{
public:
B( void ) {}
B( const B & b ) {}
};
我知道调用B
类的复制构造函数不会调用A
类的复制构造函数,并且我们可以使用初始化列表为了做得好。
我也知道使用using
来继承构造函数。
但是标准对于一个没有明确提供复制构造函数的派生类的确切要求是什么,而基类呢:
class A
{
public:
A( void ) {}
A( const A & a ) {}
};
class B: public A
{};
我一直认为编译器会隐式定义类B
的复制构造函数,从而隐藏了不会被调用的类A
的复制构造函数。
然而,看起来并非如此,并且调用A
复制构造函数。
在OS X 10.10上使用Clang进行编译。
这是强制性的东西,还是可以实现定义的东西,这意味着我们不应该依赖这种行为?
在C ++标准中,我发现了以下内容,但对我来说显然不是很清楚:
当一个类的继承构造函数被隐式定义时 odr-used(3.2)创建其类类型的对象(1.8)。一个 隐式定义的继承构造函数执行set 由用户编写的类的初始化 具有mem-initializer-list的该类的内联构造函数 只有mem-initializer有一个mem-initializer-id来命名基数 using声明的nested-name-specifier中表示的类 和下面指定的表达式列表,以及 函数体中的复合语句为空(12.6.2)。
我真的很乐意按照标准对其进行澄清,并考虑到多重继承。
答案 0 :(得分:3)
来自http://en.cppreference.com/w/cpp/language/copy_constructor(强调我的):
隐式定义的复制构造函数
如果隐式声明的复制构造函数既未删除也未删除 琐碎的,它被定义(即,生成一个函数体和 编译)编译器如果使用odr。对于工会类型, 隐式定义的复制构造函数复制对象表示 (如std :: memmove)。对于非联合类类型(类和结构), 构造函数执行对象基础的完整成员副本 和非静态成员,在初始化顺序中,使用direct 初始化。
因此,似乎编译器生成的复制构造函数将调用基本复制构造函数,就像它调用成员的复制构造函数一样。