看这段很简单的代码:
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
{
public:
A()
{
cout << "A";
}
A(const A& a)
{
cout << "C";
}
A & operator = (const A& a)
{
cout << "B";
return *this;
}
~A()
{
cout << __FUNCTION__;
}
};
A fun(A a)
{
return a;
}
A fun1(const A& a)
{
return a;
}
A& fun2(A& a)
{
return a;
}
int _tmain(int argc, _TCHAR* argv[])
{
A a1;
A a2 = fun1(a1);
cout << endl;
}
情况1:
main函数中执行:
A a1;
A a2 = fun(a1);
cout << endl;
程序输出为:
ACCA::~A
A::~AA::~A
解释:
1.首先创建一个对象a1,调用构造函数会输出A。
2.然后调用fun()函数,由于fun函数是按值传递参数,所以会创建一个a1的拷贝,即临时对象,我们把这个拷贝命名为copy1,调用拷贝构造函数输出C。
3.由于fun函数的返回值类型是类A,所以在return的时候,会创建返回值的一个拷贝copy2,所以又会调用拷贝构造函数输出C。
4.fun函数执行完成后,临时对象copy1被销毁,调用析构函数输出A::~A。
5.执行a2=fun(a1)的等号时,不会调用拷贝构造函数,而是把copy2赋给a2,a2就相当于无名对象copy2的名字。
6.main函数执行完,按顺序析构a2,a1,输出A::~AA::~A。
情况2:
main函数中执行:
A a1;
fun(a1);
cout << endl;
输出为:
ACCA::~A
A::~AA::~A
解释:和情况1中不同的只是fun返回的对象没有用到,copy2就立即被析构,在输出回车之前输出A::~A。
情况3:
A a1;
A a2 = fun1(a1);
cout << endl;
输出为:
AC
A::~AA::~A
解释:fun1传递的是引用,所以传递参数时不会创建临时对象进行拷贝,所以只在返回的时候输出一个C。
情况4:
A a1;
fun1(a1);
cout << endl;
输出为:
ACA::~A
A::~A
不解释,上文有。
情况5:
A a1;
A a2 = fun2(a1);
cout << endl;
输出为:
AC
A::~AA::~A
解释:注意与情况3的区别,尽管输出是一样的,当执行过程不一样。fun2参数传递的是引用,返回的也是引用,所以在执行fun2过程中都不会进行对象拷贝。fun2执行完后返回,在执行a2 = fun2(a1)创建对象a2时会调用拷贝构造函数,输出C。
情况6:
A a1;
fun2(a1);
cout << endl;
输出为:
A
A::~A
不解释。
情况7:
A a1;
A a2 = a1;
cout << endl;
输出:
AC
A::~AA::~A
解释:A a2 = a1;创建a2时是通过调用拷贝构造函数创建而不是重载的=函数。
情况8:
A a1;
A a2;
a2 = a1;
cout << endl;
输出为:
AAB
A::~AA::~A
解释:a2已经创建,执行a2=a1进行赋值,会调用重载的=操作符,而不是拷贝构造函数,所以输出B。