我有两个关于重载的问题。
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/