拷贝构造函数参数必须是引用。
解释如下:
先看代码:
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
class People{
private:
string m_strName;
public:
People(){}
People(string _name){
cout << "make init"<< endl;//构造初始化
m_strName = _name;
}
People(People &p){
cout << "copy init" << endl;//拷贝初始化
m_strName = p.m_strName;
}
People& operator = (const People &p)
{
cout << "assignment operator"<<endl;
m_strName = p.m_strName;
return *this;
}
void text_fun(People a){
//会调用拷贝初始化函数 People example = a;
}
};
int main(int argc, char *argv[])
{
People A("a");//直接初始化
People B("b");
B = A;//用的运算符重载
People C = A;
C.text_fun(B);
}
看运行结果:
make init
make init
assignment operator
copy init
copy init
对结果的解释:
1.第一个make init是因为A用的直接初始化方法,调用了拷贝构造函数
2.第二个make init同理于第一个
3.第三行assignment operator是由于我对“=”进行了运算符重载
4.第四行C之前没有这个对象,它是通过A对象的拷贝的方式出生的,因此调用的时拷贝构造函数。
5.由于代码中调用了 C.text_fun(B);B以值传递的方式作为行参,因此在text_fun(B)这个过程,存在隐含的People example = B,然后B这个对象进入text_fun()函数体。在people example = B这个过程存在拷贝构造函数,因此有了结果中第五行的打印。
拷贝构造函数参数必须是引用。
原因:避免拷贝构造函数无限制的递归下去。
解释:
假设参数不是引用,则:
第一步调用的时C.text_fun(B);
相当于C.text_fun(People example );即People example = B;
而example肯定调用的是拷贝构造函数去构造example。
然后执行的是example(B)操作.
example(B)又等价于People example_2 = B;
而example_2肯定调用拷贝构造函数去构造example_2。
然后执行example_2(B)操作。
无限递归没有尽头!!!
因此,参数必须要是引用,这样可以C.text_fun(B)时候,执行的是引用传递,避免构造example。