Mat*_*rom 13 c++ constructor g++
在工作中,我们有一个带有昂贵构造函数的类,所以我们希望尽可能少地调用它.我们仔细研究了它的用法并尝试使代码更加友好,所以说.
但是我们在g ++编译器中发现了一个奇怪的地方,我们不明白发生了什么.
请考虑operator +的两个实现
const Imaginary Imaginary::operator+(const Imaginary& rhs) const
{
Imaginary tmp(*this);
tmp.append(rhs);
return tmp;
}
Run Code Online (Sandbox Code Playgroud)
和
const Imaginary Imaginary::operator+(const Imaginary& rhs) const
{
return Imaginary(*this).append(rhs);
}
Run Code Online (Sandbox Code Playgroud)
我已将打印输出放在各种构造函数中,并使用以下小程序
int main(int argc, char* argv[])
{
Imaginary x(1, 1);
Imaginary y(2, 1);
Imaginary c = x + y;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我通过operator +的第一个实现得到了这个打印
int/int ctor
int/int ctor
Copy ctor
Run Code Online (Sandbox Code Playgroud)
当使用operator +的第二个变体时,我得到以下内容
int/int ctor
int/int ctor
Copy ctor
Copy ctor
Run Code Online (Sandbox Code Playgroud)
在这里我们看到g ++能够在一种情况下优化掉一次对复制构造函数的调用,而不是后一种情况.令我惊讶的是,它设法用更笨拙的实现来实现它,我把它保存到临时.
现在我可以更多地理解它,如果它是另一种方式,但显然它不是,现在我希望也许你可以在这个问题上启发我.
我应该补充一点,当我们添加--no-elide-constructors作为g ++的标志时,我得到以下打印输出
int/int ctor
int/int ctor
Copy ctor
Copy ctor
Copy ctor
Run Code Online (Sandbox Code Playgroud)
问候,马蒂亚斯
如果编译器无法内联append,则无法确定返回值是否为目标对象.然后它不知道临时被返回,并且不能在适当的位置构建它.
你会有同样的行为:
Imaginary tmp(*this);
return tmp.append(rhs);
Run Code Online (Sandbox Code Playgroud)
如果返回值对append编译器不透明(在另一个编译单元中定义),则会阻止优化.