c++中的临时对象如何影响效率

How the temporary objects in c++ affect the efficiency?

本文关键字:影响 效率 何影响 临时对象 c++      更新时间:2023-10-16

我读过一篇关于CodeProject的文章http://www.codeproject.com/Tips/103648/C-Tip-How-to-eliminate-Temporary-Objects.

Complex y,z;
Complex x=y+z; /* initialization instead of assignment */

我很困惑,为什么第二个语句没有创建一个临时对象?编译器是如何工作的?

C++中有一条规则,允许编译器省略临时变量,如果它们直接用于初始化
无论如何,利用它的回旋余地,编译器可以在没有这个规则的情况下优化示例,这也有同样的效果。

12.8复制和移动类对象§32

当满足某些条件时,允许实现省略类的复制/移动构造对象,即使该对象的复制/移动构造函数和/或析构函数有副作用。在这种情况下,该实现将省略的复制/移动操作的源和目标简单地视为两个不同的指代同一物体的方式,而该物体的破坏发生在较晚的时候如果没有优化,这两个对象何时会被销毁。123复制/移动的省略在以下情况下(可以组合为消除多个副本):
--在具有类返回类型的函数的return语句中,当表达式是非易失性自动对象(函数或catch子句参数除外),具有相同的cvunqualified类型作为函数返回类型,可以通过构造来省略复制/移动操作将自动对象直接转换为函数的返回值
--在throw表达式中,当操作数是非易失性自动对象的名称(而不是函数或catch子句参数),其作用域没有扩展到最里面的末尾之外封闭try块(如果有),从操作数到异常的复制/移动操作通过将自动对象直接构造到异常对象中,可以省略对象(15.1)
--尚未绑定到引用(12.2)的临时类对象何时被复制/移动对于具有相同cv不合格类型的类对象,可以通过将临时对象直接构造为省略的复制/移动的目标
--当异常处理程序的异常声明(第15条)声明了相同类型的对象时(除了cv资格)作为例外对象(15.1),可以省略复制/移动操作如果程序的意义除了执行由声明的对象的构造函数和析构函数外,将保持不变异常声明。

在您提供的链接中的第一个示例中,赋值运算符被调用:

Complex x, y, z;
x=y+z;

在您提供的链接中的第二个示例中,构造函数被调用:

Complex y,z;
Complex x=y+z;

但在这两种情况下,都会创建一个临时对象(包含x+y的值)。

所以我非常怀疑这个链接的正确性。

我很乐意阅读你的问题的任何答案,否则会解释。。。


我们可以避免的临时对象通常是通过值而不是引用传递给函数或从函数返回的对象。

例如,在下面的Complex::operator+=中,当函数被调用时,在堆栈上创建一个临时对象,当函数返回时,在栈上创建另一个临时物体:

Complex Complex::operator+=(Complex num)
{
    this->real += num.real;
    this->imag += num.imag;
    return *this;
}
void func()
{
    Complex a(1,2);
    Complex b(3,4);
    a += b;
    ...
}

为了消除这两个临时对象,您可以简单地通过引用传递和返回:

Complex& Complex::operator+=(Complex& num)
{
    ...
}

请注意,通过引用传递参数在成员函数和全局函数中都是可行的,但仅在成员函数中通过引用返回自变量是可行的(除非您从全局函数返回全局变量,但在大多数情况下这是毫无意义的)。