c++ - 在 C++ 中重载运算符 + 和 -

标签 c++ operator-overloading overloading

我有两个关于重载的问题。

1- 为什么有时会使重载运算符成为非成员函数?

friend Class operator-(const Class &rhs);

2-有什么区别

Class operator+(const Class &c1, const Class &c2);

Class operator+(const Class &rhs);

如果我想添加两个对象 C3 = C1 + C2?

感谢任何帮助...

最佳答案

如果将二元运算符重载为成员函数,它会以非对称方式结束:左操作数必须是运算符重载的确切类型,但右操作数可以是任何可以转换为正确类型的类型。

如果您使用非成员函数重载运算符,则两个操作数都可以转换以获得正确的类型。

你所拥有的第二点看起来像是同一点的具体示例,实际上根本不是任何独立的东西。这是我正在谈论的具体示例:

class Integer {
    int val;
public:
    Integer(int i) : val(i) {}
    operator int() { return val; }

    // Integer operator+(Integer const &other) const { return Integer(val + other.val); }

    friend Integer operator+(Integer const &a, Integer const &b) { 
        return Integer(a.val + b.val);
    }
};


int main() { 
    Integer x(1);

    Integer y = x + 2; // works with either operator overload because x is already an Integer

    Integer z = 2 + x; // works with global overload, but not member overload because 2 isn't an Integer, but can be converted to an Integer.
    return 0;
}

还要注意,即使 friend 的定义函数在 Integer 的类定义中,它被声明为友元的事实意味着它不是成员函数——将其声明为friend使其成为全局函数,而不是成员。

底线:这样的重载应该通常作为自由函数而不是成员函数来完成。为用户提供一个正确(彻底)工作的操作符比像“更面向对象”这样的理论考虑更重要。必要时,例如当运算符的实现需要虚拟时,您可以做一个两步版本,其中您提供一个(可能是虚拟的)成员函数来完成真正的工作,但重载本身是一个自由函数在其左操作数上调用该成员函数。一个相当常见的例子是重载 operator<<对于层次结构:

class base { 
    int x;
public:
    std::ostream &write(std::ostream &os) const { 
        return os << x;
    }
};

class derived : public base { 
    int y;
public:
    std::ostream &write(std::ostream &os) const { 
        return (base::write(os) << y);
    }
};

std::ostream &operator<<(std::ostream &os, base const &b) {
    return b.write(os);
}

这既支持多态实现(如有必要,也支持访问基类的 protected 成员),而无需放弃运算符的正常特性来获取它。

将二元运算符重载为自由函数的主要异常(exception)是赋值运算符(operator=operator+=operator-=operator*= 等)。转换会产生一个临时对象,您无论如何都不能分配给它,因此对于这种特殊情况,重载应该(事实上必须是)成员函数。

关于c++ - 在 C++ 中重载运算符 + 和 -,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11681186/

相关文章:

c++ - 如何使用 OpenGL ES2、GLSL、C++ 将模型矩阵数据缓冲到纹理中?

c++ - 析构函数可以在 const 对象上调用非常量函数吗?

c++ - 尝试使用 stringstream 将字符串转换为 int

c++ - 为什么非限定名称查找会找到所有重载声明

c++ - 如何在类 obj 中使用 enable_if?

c++ - 从 glm::project 输出计算 z-buffer

c++ - 派生类中与基类不同的重载运算符

c++ - 运算符重载 [][] 二维数组 C++

c++ - 制作一元运算符二进制

scala - 对重载定义的不明确引用,来自 Java 库