构造函数拷贝赋值函数的N种调用情况
1.C++对传参合传返回值时构造的优化处理
#include<iostream>
usingnamespacestd;
classDate
{
public:
Date(intyear
= 1990,intmonth = 1,intday
= 1)
{
}
Date(constDate&
d)
{
cout<<"Date(const Date& d)"<<endl;
}
~Date()
{
cout<<"~Date()"<<endl;
}
private:
int_year;
int_month;
int_day;
};
(1)Date对象做参数传值
voidFunc1(Date
d)
{
}
intmain()
{
Date d1;
Func1(d1);
return0;
}
输出结果为:
(2)Date对象做参数传引用
voidFunc1(Date& d)
{
}
intmain()
{
Date d1;
Func1(d1);
return0;
}
输出结果为:
通过(1)(2),我们可以看出传引用可以不调用拷贝构造函数
(3)Date对象做返回值传值
Date Func2()
{
Date d;
returnd;
}
intmain()
{
Date d1;
Func2();
return0;
}
输出结果为:
(4)Date对象做返回值传引用
Date& Func2()
{
Date d;
returnd;
}
intmain()
{
Date d1;
Func2();
return0;
}
输出结果为:
通过(3)(4)比较可以看出,当传引用返回时,则不调用构造函数。
但要注意的一点则是:不要返回一个临时变量的引用!
(5)编译器优化问题
i.Date对象做临时返回值传引用(不能使用引用!)
Date& Func3()
{
returnDate();
}
intmain()
{
Date d1;
Func3();
return0;
}
ii.Date对象做临时返回值传值
Date Func3()
{
returnDate();
}
intmain()
{
//情况一
Date d1;
d1 = Func3();
return0;
}
输出结果为:
没有调用拷贝构造函数的原因是编译器对其做了优化处理—Func3函数返回一个临时变量,
本来函数的返回值会通过拷贝构造创建一个临时变量,再将临时变量的值赋给d3,但由于
此时已经是一个临时变量,所以编译器就自动进行了优化。
//情况二
//情况三
通过上述三种情况的对比,显然情况三更优化!
2.Test1中调用了_2_次AA的拷贝构造函数,_1__次AA的赋值运算符函数的重载。
Test2中调用了_2__次AA的拷贝构造函数,_0__次AA的赋值运算符函数的重载。
Test3中调用了_3__次AA的拷贝构造函数,0_次AA的赋值运算符函数的重载。
classAA
{};
AA f (AA a)
{
returna ;
}
voidTest1 ()
{
AA a1 ;
a1 = f(a1);
}
voidTest2 ()
{
AA a1 ;
AA a2 = f(a1);
}
voidTest3 ()
{
AA a1 ;
AA a2 = f(f(a1));
}
分析如下: