当前位置:天才代写 > tutorial > C语言/C++ 教程 > C++中按值返回和返回值优化代码

C++中按值返回和返回值优化代码

2017-11-03 08:00 星期五 所属: C语言/C++ 教程 浏览:466

副标题#e#

C++和C语言对比,最为人诟病的就是其机能问题,凡是一条C语言经编译器表明后,可以牢靠转换成5—10条汇编语言,可是一条C++语言,就没有这么幸运了,大概会是3条汇编语言,也大概是300条。C++影响机能的原因许多,个中一个就是姑且工具的建设和销毁。这里我简述一种淘汰建设姑且工具的要领–返回值优化问题

许多时候,函数需要按值返回,这个中就会不行制止地涉及到姑且工具的建设和销毁。假设界说如下的Complex类:

class Complex
{
friend Complex operator +(const Complex&,const Complex&);
public:
Complex(double r=0, double i=0):real(r),imag(i)
{
cout<<"I'm in constructor"<<endl;
}
Complex(const Complex& c):real(c.real),imag(c.imag)
{
cout<<"I'm in copy constructor"<<endl;
}
Complex& operator =(const Complex& c)
{
real=c.real;
imag=c.imag;
cout<<"I'm in assignment"<<endl;
return *this;
}
void print()
{
cout<<real<<"+"<<imag<<"i"<<endl;
}
~Complex()
{
cout<<"I'm in destructor"<<endl;
}
private:
double real;
double imag;
};
Complex operator +(const Complex& a,const Complex& b)
{
/*Complex retVal;
retVal.real=a.real+b.real;
retVal.imag=a.imag+b.imag;
return retVal;*/
cout<<"calling plus"<<endl;
// return Complex(a.real+b.real,a.imag+b.imag);
Complex retVal(a.real+b.real,a.imag+b.imag);
return retVal;
}


#p#副标题#e#

个中的友元函数operator + 是一个按值返回的函数。编译器会将这个函数表明成如下:

void Complex_Add(const Complex& __result,
const Complex& c1,
const Complex& c2)
{
......
}

界说一下语句:Complex a(1,1),b(2,2),c;

c=a+b;

a和b相加的功效赋值给工具c的进程,可以被转化为:

Complex __tempResult;
Complex_Add(__tempResult, a,b);
c=__tempResult;

可以看出,在上述的一个简朴的操纵中,编译器会隐蔽地发生一个姑且工具__tempResult。这是发生的第一个姑且工具,先记下,可是这大概并不是独一的一个。好比当operator +如下实现时

Complex operator +(const Complex& a,const Complex& b)
{
Complex retVal;
retVal.real=a.real+b.real;
retVal.imag=a.imag+b.imag;
return retVal;
}

在operator +函数内部又会发生一个姑且工具retVal,综合一下,编译器在碰着如上的函数界说及挪用时会发生如下表明:

void Complex_Add(const Complex& __tempResult,
const Complex& c1,[Page] const Complex& c2)
{
Complex retVal;
retVal.Complex::Complex();
retVal.real=a.real+b.real;
retVal.imag=a.imag+b.imag;
__tempResult.Complex::Complex(retVal);
retVal.Complex::~Complex();
return;
}

#p#副标题#e#

所以

Complex a(1,1),b(2,2),c;
c=a+b;的运行功效是:
I'm in constructor
I'm in constructor
I'm in constructor
I'm in constructor
I'm in copy constructor
I'm in destructor
I'm in assignment
I'm in destructor
I'm in destructor
I'm in destructor
I'm in destructor

下面临措施举办优化,可以通过消除上述进程中发生的两个姑且工具来淘汰工具的建设和析构

首先可以对operator +函数内部的retVal姑且工具举办优化,使得直接用__tempResult代替retVal

void Complex_Add(const Complex& __tempResult,
const Complex& c1,
const Complex& c2)
{
__tempResult.Complex::Complex();
__tempResult.real=a.real+b.real;
__tempResult.imag=a.imag+b.imag;
return;
}

以上是Efficient C++中的表明,可是我认为__tempResult.Complex::Complex()不该该在函数内部挪用,不外并不影响挪用次数。

以上即是RVO优化,许多编译器都是支持的,为了防备某些编译器不支持,可以显式地将operator +函数如下实现:

Complex operator +(const Complex& a,const Complex& b)
{
return Complex(a.real+b.real,a.imag+b.imag);
}

以上这种形式称为未定名变量,有些编译器拒绝对已定名变量的RVO优化(好比前面的retVal),这样我们就消除结局部的retVal姑且变量。

下面再谈谈__tempResult姑且变量的发生,以及消除的要领:

Complex a(1,1),b(2,2),c;

c=a+b;

#p#副标题#e#

#p#分页标题#e#

界说c的时候会挪用默认的结构函数举办初始化,因此第一条语句执行完之后,c已经是一个存在的工具,所以第二条语句并没有权利去直接修改c的内容,必需要通过挪用赋值操纵符(=),因此必需要发生一个姑且工具,详细表明语句前面已经先容过,即__tempResult的发生原因。

可是假如在执行第二条语句的时候c没有旧的内容,即c不是一个已经存在的工具,那么就可以直接挪用结构函数,而不需要=操纵符,这样也就可以制止了__tempResult 的发生。

所以如下的操纵

Complex a(1,1),b(2,2);

Complex c=a+b;

其运行功效为

I'm in constructor
I'm in constructor
I'm in constructor
I'm in destructor
I'm in destructor
I'm in destructor

只挪用了三次结构函数和析构函数,和没有优化前对比,机能获得了很大的晋升。

来历:http://blog.csdn.net/SeeSeaBee/archive/2007/06/27/1668825.aspx

 

    关键字:

天才代写-代写联系方式