拷贝构造函数起作用的三种情况:
1.当用类的对象去初始化同类的另一个对象时。
Date d2(d1);
Date d2 = d1; //初始化语句,并非赋值语句。
2.当函数的形参是类的对象,调用函数进行形参和实参结合时。
void Func(A a1) //形参是类Date的对象a1
{ }int main( )
{A aFunc(a2); //调用Func时,实参a2是类Date的对象,将调用拷贝构造函数,初始化形参a1.return 0;
}
3.当函数的返回值是对象,函数执行完成返回调用者时。
A Func1()
{A a1(4);return a1; //函数的返回值是对象
}int main( )
{A a2;a2 = Func1(); //函数执行完成,返回调用者时,调用拷贝构造函数return 0;
}在函数Func1( )内,执行语句“return a1;”时,将会调用拷贝构造函数将a1的值复制到一个匿名对象中,
这个匿名对象是编译系统在主程序中临时创建的。函数执行结束时对象a1消失,但临时对象会存在于语句
“a2 = Func( )”中。执行完这个语句后,临时对象的使命也就完成了,该临时对象便自动消失了。
系统在什么情况下会进行优化?
1.当拷贝构造存在连续的赋值情况的时候,
2.当多个临时对象连续赋值的时候 , 简单点来说就是,在一次拷贝构造结束后,并没有直接返回给要创建的对象而是又再次进行了拷贝构造。
或者是,创建了一个临时对象,来进行拷贝构造,然后又返回了一个临时对象,再用这个返回的临时对象继续拷贝构造。这时候,系统就会自动优化。
看下面的题目,更深层次的理解VS下如何优化 :
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));
}