拷贝构造函数参数为什么必须是引用?
为什么C++规定拷贝构造函数的参数必须是引用类型?如果拷贝构造函数参数按值传递会发生什么?解释这背后的语言设计原理(无限递归/拷贝链)。
回答
Yahuda
核心原因:如果拷贝构造函数参数按值传递,调用拷贝构造函数时会触发无限递归。
详细分析:假设class A的拷贝构造函数参数为值传递(A(A other)):
- 当调用
A b(a)时,需要将实参a拷贝给形参other - 形参other的构造需要调用拷贝构造函数(因为传值产生副本)
- 又要拷贝a到other,再次触发拷贝构造函数
- 形成无限递归——编译错误(有些编译器直接报错)
必须用const引用:A(const A& other)。原因:
- 避免无限递归
- const保证不修改原对象
- 引用避免不必要的拷贝
例外(非const引用):A(A& other)也是合法的拷贝构造函数,但不支持从临时对象拷贝(右值),在现代C++中通常与移动构造函数配合使用。C++11起还应有A(A&& other)移动构造函数。
注意:如果未显式定义拷贝构造函数,编译器会生成默认逐成员拷贝。自定义拷贝构造函数时务必传引用。