c++ - 为什么要在类之外定义运算符 + 或 +=,以及如何正确执行?

标签 c++ operators operator-overloading

我对两者的区别有点困惑

Type  operator +  (const Type &type);
Type &operator += (const Type &type);

friend Type  operator +  (const Type &type1, const Type &type2);
friend Type &operator += (const Type &type1, const Type &type2);

首选哪种方式,它们是什么样的,什么时候应该使用?

最佳答案

运算符的第一种形式是您将在类 Type 中定义的形式。

运算符的第二种形式是您将定义为与 Type 类在同一命名空间中的独立函数。

定义独立函数是一个非常好的主意,因为这样这些函数的操作数可以参与隐式转换

示例

假设这个类:

class Type {
    public:
    Type(int foo) { }

    // Added the const qualifier as an update: see end of answer
    Type operator + (const Type& type) const { return *this; }
};

然后你可以写:

Type a = Type(1) + Type(2); // OK
Type b = Type(1) + 2; // Also OK: conversion of int(2) to Type

但你不能写:

Type c = 1 + Type(2); // DOES NOT COMPILE

operator+ 作为自由函数也允许最后一种情况。

第二种形式的运算符的错误在于它通过直接调整其操作数的私有(private)成员来执行加法(我假设,否则它不需要成为 friend )。它应该那样做:相反,运算符也应该在类中定义并且独立的函数应该调用它们。

要看看结果如何,让我们寻求大师的服务:http://www.gotw.ca/gotw/004.htm .滚动到最后,了解如何实现独立功能。

更新:

正如 James McNellis 在他的评论中指出的那样,给出的两种形式还有另一个区别:在第一个版本中,左侧不是 const 限定的。由于 operator+ 的操作数实际上不应该作为加法的一部分进行修改,因此始终对它们进行 const 限定是一个非常非常好的主意。我的示例中的类 Type 现在可以执行此操作,而最初它没有。

结论

处理运算符++=的最佳方式是:

  1. 在您的类中将 operator+= 定义为 T& T::operator+=(const T&);。这是实现添加的地方。
  2. 在你的类中将 operator+ 定义为 T T::operator+(const T&) const;。该运算符将根据前一个运算符实现。
  3. 在类外提供一个自由函数T operator+(const T&, const T&);,但在同一个命名空间内。这个函数会调用成员 operator+ 来完成这项工作。

您可以省略第 2 步,直接调用自由函数 T::operator+=,但根据个人喜好,我希望将所有加法逻辑保留在类中。

关于c++ - 为什么要在类之外定义运算符 + 或 +=,以及如何正确执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4652932/

相关文章:

c++ - 从函数和复制构造函数返回的对象

c++ - 字段类型不完整

c++ - 模板和 STL 容器

ios - 具有自定义运算符的 Swift 类流式 API 设计

c# - 如何使用 "?"运算符缩小此特定 if 行(杂乱)

c# - 可重载运算符 == 和 !=

c++ - 如何修复 C++ 中重载加法运算符的堆栈溢出

c++ - 包含在 .h 文件和 .c 文件中的区别

sql - 如何查询 PostgreSQL 9.5 JSONB 列中是否存在某个键?

javascript分配属性语句返回父对象