先从我最近遇到的一个诡异的现象说起,来看一段代码:
#include <iostream>
using namespace std;
class test
{
public:
test(){}
test(test &t)
{
data = t.data;
}
test func(test t)
{
test m;
return m;
}
public:
double data;
};
int main()
{
test t1,t2;
test t3 = t1.func(t2);
return 0;
}
gcc 编译结果如下:

是不是有点不懂是啥意思,其实大体意思是拷贝构造函数提供的函数参数与所需要的不符合,但是拷贝构造函数的形式参数只能为自身类对象的引用而不能为对象(原因待会后面会阐述),而这里的“.....for call to "test::test(test)"”就不太能理解了,,那好吧,,,我们在做一个实验,,将拷贝构造函数改成
test(test t)
{
data = t.data;
}
重新编译,结果如下:

哈,意料之中,还是编译通不过,因为拷贝构造函数的函数形式参数不可以为自身对象,最多为引用(原因后述),不过现在也不是一无所获,这次编译直接提示你可能需要的类型为"test (const test&)",那就再改吧,按照提示,如下改成const test& t
test(const test &t)
{
data = t.data;
}
这次编译成功通过。
为了准确的定位问题原因,我们再做一个实验,将整体代码改成如下形式
#include <iostream>
using namespace std;
class test
{
public:
test(){}
test(test &t)
{
data = t.data;
}
test func(test t)
{
test m;
return m;
}
public:
double data;
};
int main()
{
test t1,t2;
/
test t3;
t1.func(t2);
return 0;
}
编译通过,这次代码,拷贝构造函数依旧是test &形参,只不过,main函数里调用func的时候我没有用一个对象去接受返回值,这样子就通过了,而之前用一个对象变量去接受函数返回就失败。
好了,现在能够定位错误了,最关键的问题就在于 func函数返回值上,根据上述的实验,函数将对象作为返回值并且赋予外部的另一个变量的时候,是调用了类的拷贝构造函数,而且此时的拷贝构造函数的参数是“const myclass &"形式的"myclass &"都不行,为啥呢? 当时到这一步的时候本人就很困惑,为何此时一定要用const呢???
------------------------------------------华丽的分割----------------------------------------
先回味一下c++拷贝构造函数的一些特性: