2011-11-15 98 views
2

考虑以下代码拷贝构造从基准

class Foo { 
private: 
    Bar bar; //note: no reference 

public: 
    Foo(Bar& b) : bar(b) { } 
}; 

将禁止获得拷贝构造?

+3

@ildjarn:还有其他的可能吗? (当然,除了简单的编译失败之外。) –

+0

@Oli:没有,我暂时感到困惑。 ; - ] – ildjarn

回答

3

这取决于Bar的公共构造函数的签名,无论是显式还是隐式定义。

首先,C++标准允许对引用进行隐式转换,只要基本类型的唯一区别是目标类型至少为源版本的cv-qualified,则使用偏序

没有CV-合格音响ER < const
没有CV-合格音响ER < volatile
:此表中(C++ 11,§3.9.3/ 4)中所定义没有CV-合格音响ER < const volatile
const                     < const volatile
volatile         < const volatile

因此,考虑到这一点以及§12.8/ 2:

的非模板构造为X类是一个拷贝构造如果第一个参数是X&类型,const X&volatile X&const volatile X&的,并且或者没有其他参数,否则所有其他参数都有默认参数。

如果酒吧有以下签名的任何构造:

Bar(Bar&); 
Bar(Bar const&); 
Bar(Bar volatile&); 
Bar(Bar const volatile&); 

然后是,b将被复制到构建Foo::bar


编辑:这是不正确的,我在想operator=和排位赛的一个举动,赋值运算符的详细信息。

注意,它可能有一个符合条件的构造不是一个拷贝构造函数:

Bar(Bar); 

这将工作(读:编译),但它在技术上不是拷贝构造函数。

+0

不会有'Bar(const Bar&)'拷贝构造函数的工作呢? –

+0

@Fred:的确,我的一个疏忽,编辑。 – ildjarn

+0

“这将工作(阅读:编译)”。可以?我没有一个标准的方便,但... http://ideone.com/9GIJu –

1

是的,您的成员变量bar将被复制构造,这是使用初始化列表的好处之一,而不是在构造函数的主体中赋值。

如果Bar类没有可访问的拷贝构造函数,且编译器无法生成默认的构造函数,则代码将无法编译。

当您将引用传递给复制构造函数时,通常应将其设置为const引用。