看这段很简单的代码: 代码classA
{
public:
A()
{
cout<<"A";
}
A(constA&a)
{
cout<<"C";
}
A &operator=(constA&a)
{
cout<<"B";
returnthis;
}
~A()
{
cout<<FUNCTION;
}
};
A fun(A a)
{
returna;
}
A fun1(constA&a)
{
returna;
}
A&fun2(A&a)
{
returna;
}
int_tmain(intargc, _TCHARargv[])
{
A a1;
A a2=fun1(a1);
cout<<endl;return 0;
}情况1:
main函数中执行:
A a1;
A a2=fun(a1);
cout<<endl;return 0;程序输出为:
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。 原文链接: https://www.cnblogs.com/rockstone/archive/2010/02/24/1672994.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/8347
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!