有如下类
class AA
{
public:
AA()
{
cout<<"AA()"<<endl;
}
AA(const AA& a)
{
(void)a;
cout<<"AA(const AA& a)"<<endl;
}
AA& operator=(const AA& a)
{
cout<<"AA& operator=(const AA& a)"<< endl;
return (AA&)a;
}
~AA()
{
cout<<"~AA()"<<endl;
}
};
这里我们只关心调用构造函数,拷贝构造函数,赋值运算符重载和析构函数的次数,其他操作没有给出
一、传参的优化
1)
void fun1(AA a)
{
(void)a;
}
int main()
{
AA a;
fun1(a);
return 0;
}
一次构造,一次拷贝构造,两次析构
2)
void fun1(AA& a)
{
(void)a;
}
int main()
{
AA a;
fun1(a);
return 0;
}
这次我们用引用接收fun1的参数
一次构造,一次析构
3)
void fun1(AA a)
{
(void)a;
}
int main()
{
fun1(AA());
return 0;
}
这里把AA创建出来的临时对象直接传给fun1函数
一次构造,一次析构
4)
AA fun2()
{
AA ret;
return ret;
}
int main()
{
AA a;
a = fun2();
return 0;
}
这里使用传值返回
两次构造,一次赋值运算符重载,两次析构
但是,这是编译器优化以后的结果,如果不经过优化的话,结果应该是两次构造函数,一次拷贝构造,一次析构,一次赋值运算符重载,两次析构
5)
AA fun2()
{
AA ret;
return ret;
}
int main()
{
AA a = fun2();
return 0;
}
返回值和赋值构造函数在一个步骤中,编译器优化,合二为一,可以认为将fun2拷给构造的对象直接用来拷贝构造a
这里产生了一个构造,一个拷贝构造,两个析构
6)
AA fun2()
{
return AA();
}
int main()
{
AA a = fun2();
return 0;
}
有如下问题:
Test1中调用了___次AA的拷贝构造函数,___次AA的赋值运算符函数的重载。
Test2中调用了___次AA的拷贝构造函数,___次AA的赋值运算符函数的重载。
Test3中调用了___次AA的拷贝构造函数,___次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));
}
Test1
Test2
Test3