您的位置:首页 > 编程语言 > C语言/C++

C++拷贝构造的优化

2017-08-01 13:03 288 查看
对于拷贝构造来说,归根结底,落脚点在构造函数上。所以调用拷贝构造函数的时候,一定是这个对象不存在的时候,比如下面这句

A a =A(10)


那么,a是不存在的,而且是通过其它的A对象构造出来的,那么则调用的是拷贝构造函数。如果是

A a(1);
a =  A(10);


那么这里就调用的是赋值操作符,因为a是已经存在的对象了,不需要构造了。

那么,接下来再讨论一下拷贝构造的优化问题。如果有以下代码:

代码 1:

#include <iostream>
using namespace std;
static int i=0;
class A {
public:
A(){cout<<"A::A()"<<endl;
}
~A(){cout<<"A::~A()"<<endl;
}
A(const A& o){
i++;
cout<<"A::A(const A& 0)"<<endl;
}
private:
int t;
};
A f(A a)
{
return a;
}
int main()
{
A a1;
a1=f(a1);
return 0;
}//main()函数中调用了2次A的拷贝构造函数,1次A的赋值运算符函数的重载。


解释:1次A的赋值运算符函数重载(类中没有定义是调用默认的重载运算符)。



代码2:

#include <iostream>
using namespace std;
static int i=0;
class A {
public:
A(){cout<<"A::A()"<<endl;
}
~A(){cout<<"A::~A()"<<endl;
}
A(const A& o){
i++;
cout<<"A::A(const A& 0)"<<endl;
}
private:
int t;
};
A f(A a)
{
return a;
}
int main()
{
A a1;
A a2=f(a1);
return 0;
}//main()函数中调用了2次A的拷贝构造函数,0次A的赋值运算符函数的重载。


解释:在创建对象的同时赋值给该对象为拷贝构造(因为a2对象原先不存在),而不是赋值运算符的重载,所以赋值运算符的重载0次。



代码3:

#include <iostream>
using namespace std;
static int i=0;
class A {
public:
A(){cout<<"A::A()"<<endl;
}
~A(){cout<<"A::~A()"<<endl;
}
A(const A& o){
i++;
cout<<"A::A(const A& 0)"<<endl;
}
private:
int t;
};
A f(A a)
{
return a;
}
int main()
{
A a1;
A a2=f(f(a1));
return 0;
}//main()函数中调用了3次A的拷贝构造函数,0次A的赋值运算符函数的重载。


解释:在函数调用过程中,实际上优化了两次:第一次发生在第一次return a的时候,同时将return的临时变量temp1作为函数参数再一次传入,相当于A a = temp1(构造函数并优化一次);第二此发生在第二次return a的时候,同时将return的临时变量temp2作为成员对a2初始化,相当于 A a2 = temp2(调用构造函数并优化一次)。



代码4

#include <iostream>
using namespace std;
static int i=0;
class A {
public:
A(){cout<<"A::A()"<<endl;
}
~A(){cout<<"A::~A()"<<endl;
}
A(const A& o){
i++;
cout<<"A::A(const A& 0)"<<endl;
}
private:
int t;
};
A f (A a)
{
cout<<"i = "<<i<<endl;
cout<<"end"<<endl;
return a;
}
int main()
{
cout<<"i = "<<i<<endl;
A a1;
f(a1);
return 0;
}//调用两次拷贝构造函数


解释:在函数参数的时候调用一次,return的时候调用一次。

代码5:

#include <iostream>
using namespace std;
static int i=0;
class A {
public:
A(){cout<<"A::A()"<<endl;
}
~A(){cout<<"A::~A()"<<endl;
}
A(const A& o){
i++;
cout<<"A::A(const A& 0)"<<endl;
}
private:
int t;
};
A f (A a)
{
cout<<"i = "<<i<<endl;
cout<<"end"<<endl;
return a;
}
A& g (A& a)
{
cout<<"i = "<<i<<endl;
cout<<"end"<<endl;
return a;
}
int main()
{
cout<<"i = "<<i<<endl;
A a1;
f(g(a1));
return 0;
}//调用两次拷贝构造函数


解释:在g()函数中,传入和返回都是引用,以为着没有新的对象生成,所以不会调用拷贝构造函数,而f()函数的调用和代码4是一样的,故调用两次拷贝构造函数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: