构造拷贝构造的N种调用情况的编译器优化
1、传参合传返回值时构造的优化处理
include<iostream>
using namespace std;
class Date
{
public:
Date()//构造
{
cout << "Date()" << endl;
}
Date(const Date& d)//拷贝
{
cout << "Date(const Date& d)" << endl;
}
Date& operator=(const Date& d)//赋值运算符
{
cout << "operator=(const Date& d)" << endl;
return *this;
}
~Date()
{
cout << "~Date()" << endl;
}
};
//Date 对象做参数传值
void fun1(Date d)//void fun1(Date& d)
{}
//Date 对象返回值传值
Date fun2()
{
Date d;
return d;
}
//Date 对象做临时返回值传值
Date fun3()
{
return Date();
}
int main()
{
Date d3 = fun3();
return 0;
}
以上为大家介绍了几种情况,我们一起来研究一下他们之间的调用关系
这里我们要记得,当对象被传递给函数或者对象从函数返回的时候,会发生对象的拷贝。
首先来看Date d2=fun2();
这句话先调用了fun2()
函数,函数中创建d(Date d
)时,先调用构造函数,然后return d
因为这里生成d的临时变量,调用了拷贝构造。然后传给main函数,原本Date d2
也调用了构造,可是这里发生了编译器优化(条件时他们在同一语句中),没有在一句时则不优化,就是下图这种情况:
接下面我们来分析另一种更加复杂的优化
对于这种类型的问题我们先分析本来是如何调用,再看是否需要优化即可
2.再完成下面的题目。
Test1中调用了2_次AA的拷贝构造函数,1_次AA的赋值运算符函数的重载。
Test2中调用了2_次AA的拷贝构造函数,0_次AA的赋值运算符函数的重载。
Test3中调用了3_次AA的拷贝构造函数,0_次AA的赋值运算符函数的重载。
class AA
{};
AA f (AA a)
{
return a ;
}
void Test1 ()
{
AA a1 ;
a1 = f(a1);
}
void Test2 ()
{
AA a1 ;
AA a2 = f(a1);
}
void Test3 ()
{
AA a1 ;
AA a2 = f(f(a1));
}
这里调用了两次拷贝构造,传值一次,返回值临时拷贝一次,没有优化
这个是本来3次,AA a2=f(a1);
中优化了一次
这里调用5次拷贝发生了2次优化,首先是a1传参一次,返回值和返回值做值传参优化为一次,因为返回的本身就是一个临时拷贝然后又那它去传参临时拷贝,所以优化了,接着就是第二次的返回值和赋值给a2,优化了一次,所以是3次。