C++ - 为什么要根据 op+= 而不是相反的方式来实现 op+?

标签 c++ operator-overloading code-reuse

为什么这样实现:

T& T::operator+=(const T&) {
  // ... implementation ...
  return *this;
}

T operator+(const T& lhs, const T& rhs) {
  T temp(lhs);
  return temp += rhs;
}

比这个更常见:

T& T::operator+=(const T& rhs) {
  *this = *this + rhs;
  return *this;
}

T operator+(const T& lhs, const T& rhs) {
  // ... implementation ...
  return some_result;
}

我在阅读的文献中多次看到人们以这种方式实现它,而从来没有相反的方式,这到底是有什么原因,还是只是偶然的巧合?

最佳答案

operator+ 必须创建一个新对象来保存结果。 operator+= 不需要新对象。

如果您根据 operator+ 编写 operator+=,那么您最终会为额外的新对象创建、赋值(或交换)和销毁付出代价,所有这些你都不需要。

除此之外,在许多处理器上,硬件直接支持 += 和类似的操作,其中结果存储回输入寄存器之一,不存储到第三个寄存器(像 +)。

顺便说一句,您的(原始的,现在已编辑的)代码中有一个错误隐藏了部分额外工作。你实际上需要:

T& T::operator+=( const T& rhs )
{
    *this = *this + rhs; // creation of temporary, move assignment, and destruction of temporary
    return *this;
}

更糟糕的是,您(又是原创的,现在已编辑)建议的 operator+ 实现无法正确返回新对象,而是返回悬空引用。这是未定义的行为。


对于那些感兴趣的人,第一个 operator+ 实现可以通过使用按值传递进一步改进:

T operator+( T lhs, const T& rhs )
{
    lhs += rhs;
    return lhs;
}

现在如果 operator+ 的左手操作数是临时的,将使用移动构造函数,避免复制。尽管使用 NRVO,但无论哪种方式,生成的代码可能都没有太多优势。

关于C++ - 为什么要根据 op+= 而不是相反的方式来实现 op+?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38579088/

相关文章:

oop - 在 Fortran 中重载等于运算符

c++ - 如何在 C++ 中将远程设备映射为数组?

Swift 可重用 View

c++ - 更新代码库以满足标准

c++ - 打开 Qt C++ 项目

c++ - 我如何着手重载 C++ 运算符以允许链接?

asp.net-mvc - 服务器控件在 ASP.Net MVC 中的什么位置?

android - 如何在 Android 中为数据库编写可重用代码

c++ - 将 double* 从 c++ dll 返回到 delphi 程序

具有模板函数的嵌套命名空间中的 C++ ADL