我正在尝试为创建的Integer类重载二进制+:
const Integer operator+(const Integer& left,const Integer& right)
{
return Integer(left.i + right.i);
}
和
const Integer operator+(const Integer& left,const Integer& right)
{
Integer tmp(left.i + right.i);
return tmp;
}
现在我学到的是,在第一种情况下,创建一个临时的Integer对象并返回,在第二种情况下,使用构造函数调用然后复制然后调用析构函数来创建通常的对象。 Ecekl对第一个问题所说的是编译器通过将对象直接构建到外部返回值的位置来利用这一点。我们从中推断出什么?我读到了关于返回值优化但是无法通过直接复制到位置事物来获得它的含义。
答案 0 :(得分:7)
绝对没有区别,在大多数情况下,一个不错的编译器会将第二种形式优化为第一种形式 - 并且在返回tmp
时将按Named Return Value Optimization (NRVO)执行复制/移动省略。
如果它使代码对您更具可读性,或者更易于维护和/或调试,则可能需要使用第二种形式。如果你关心性能,没有理由(除非你关闭了编译器优化,但这表明你对性能不感兴趣)。
但请注意,返回const Integer
并没有多大意义。由于您按价值返回,因此您应该返回Integer
:
Integer operator + (const Integer& left, const Integer& right)
{
return Integer(left.i + right.i);
}
作为最后的评论,如果Integer
有一个非explicit
构造函数接受int
(注意,这通常是),这甚至可以重写如下:不是的情况,因为接受一个参数的构造函数通常标记为explicit
以避免尴尬的隐式转换):
Integer operator + (const Integer& left, const Integer& right)
{
return left.i + right.i;
}