运算符重载:当只能涉及相同类型的对象时,成员与非成员 [英] Operator overload: Member vs. non-member when only same type objects can be involved
问题描述
这个问题很好地回答了为什么将运算符重载定义为非成员:运算符重载:成员函数与非成员函数?
This question gives a good answer why to define operator overloads as non-members: Operator overloading : member function vs. non-member function?
如果您将运算符重载函数定义为成员函数,然后编译器将像 s1 + s2 这样的表达式翻译成s1.operator+(s2).也就是说,运算符重载的成员函数在第一个操作数上调用.这就是成员函数的工作原理!
If you define your operator overloaded function as member function, then compiler translates expressions like s1 + s2 into s1.operator+(s2). That means, the operator overloaded member function gets invoked on the first operand. That is how member functions work!
但是如果第一个操作数不是一个类呢?有一个大问题如果我们想重载第一个操作数不是 a 的运算符类类型,而不是说双重.所以你不能这样写 10.0 +s2.但是,您可以为像 s1 + 10.0 这样的表达式.
But what if the first operand is not a class? There's a major problem if we want to overload an operator where the first operand is not a class type, rather say double. So you cannot write like this 10.0 + s2. However, you can write operator overloaded member function for expressions like s1 + 10.0.
现在我需要重载operator==
.在我的例子中,只比较 (a) (b) 相同 类型的对象.
Now I have a situation where I need to overload operator==
. In my case, only (a) objects of (b) the same type will be compared.
是否仍有理由将 operator==
定义为非成员,或者在这种情况下我应该将其实现为成员?
Is there a reason to still define operator==
as a non-member or should I implement it as a member in that case?
推荐答案
因为 operator==
的 LHS 和 RHS 参数具有对称语义,推荐的方法是始终将其实现为非成员在其操作数的公共接口方面(或者如果需要私有数据,则在类内将其声明为友元).
Because operator==
has symmetric semantics for its LHS and RHS argument, the recommended approach is to always implement it as a non-member in terms of the public interface of its operands (or if private data is required, to declare it as a friend inside the class).
所以
class Bla
{
public:
// complete interface to data required for comparison
auto first();
auto second();
// ... more
private:
// data goes here
};
bool operator==(Bla const& L, Bla const& R)
{
return
std::forward_as_tuple(L.first(), L.second() /*, ... */) ==
std::forward_as_tuple(R.first(), R.second() /*, ... */)
;
}
这样,L 和 R 参数都考虑到 Bla
的隐式转换(我不是说隐式转换是个好主意,但如果你有这些,最好避免意外仅在 RHS 参数中考虑它们).
This way, implicit conversion to Bla
are considered for both the L and R arguments (I'm not saying implicit conversions are a good idea, but if you have those, it's better to avoid surprises where they are only considered for the RHS argument).
这篇关于运算符重载:当只能涉及相同类型的对象时,成员与非成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!