考虑这段代码
class Foo {
private:
Bar bar; //note: no reference
public:
Foo(Bar& b) : bar(b) { }
};
Bar会复制吗?
答案 0 :(得分:3)
这取决于Bar
的公共构造函数的签名,无论是显式还是隐式定义。
首先,C ++标准允许隐式转换引用,只要底层类型的唯一区别是目标类型至少为 cv-qualified 而不是源类型,使用此表中定义的部分排序(C ++ 11,§3.9.3/ 4):
no cv-quali fi er <
const
no cv-quali fi er <volatile
no cv-quali fi 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(Bar const&);
Bar(Bar volatile&);
Bar(Bar const volatile&);
然后是,b
将被复制到Foo::bar
。
编辑: 这是错误的,我在考虑operator=
以及作为移动分配操作符的资格细节。
请注意,可以使合格的构造函数不是复制构造函数:
Bar(Bar);
这将起作用(读取:编译),但从技术上讲它不是复制构造函数。
答案 1 :(得分:1)
是的,你的成员变量bar
将被复制构造,这是使用初始化列表而不是在构造函数体中赋值的好处之一。
如果Bar
类没有可访问的拷贝构造函数且编译器无法生成缺省拷贝构造函数,则代码将无法编译。
当您将引用传递给复制构造函数时,通常应该将其作为const
引用。