在 C++ 中重载二元关系运算符的正确方法
Proper way of overloading binary relational operators in C++
在 C++ 中重载二元关系运算符的 proper/canonical 方法是什么?
使用成员函数还是friend
自由函数更好?
例如:
class X {
public:
...
// Use member function overloads
bool operator==(const X& rhs) const {
return m_text == rhs.m_text;
}
private:
std::string m_text;
};
或:
class X {
public:
...
// Use friend free function overloads
friend bool operator==(const X& lhs, const X& rhs) {
return lhs.m_text == rhs.m_text;
}
private:
std::string m_text;
};
您应该注意的一件事是隐式转换。
如果您的 class 支持来自其他类型的隐式转换,那么让 operator== 成为支持其第一个参数隐式转换的朋友可能会很有用。
在其他情况下,我认为更多的是风格问题。
没什么区别,除了
X
的实例需要位于相等运算符的左侧,成员版本才能工作。如果你想写
X x("hello");
string s("hello");
assert(s == x);
您需要一个非会员。
如果您正在实施所有二元关系运算符,那么您的 class 表面积可能会大幅增加。
我通常更喜欢这种辅助界面尽可能与主要 class 逻辑分开(当然,除非您的 class 主要关心的是比较)。
使用非友元免费运算符和最小的 public 界面可能会更好。
在 C++ 中重载二元关系运算符的 proper/canonical 方法是什么?
使用成员函数还是friend
自由函数更好?
例如:
class X {
public:
...
// Use member function overloads
bool operator==(const X& rhs) const {
return m_text == rhs.m_text;
}
private:
std::string m_text;
};
或:
class X {
public:
...
// Use friend free function overloads
friend bool operator==(const X& lhs, const X& rhs) {
return lhs.m_text == rhs.m_text;
}
private:
std::string m_text;
};
您应该注意的一件事是隐式转换。
如果您的 class 支持来自其他类型的隐式转换,那么让 operator== 成为支持其第一个参数隐式转换的朋友可能会很有用。
在其他情况下,我认为更多的是风格问题。
没什么区别,除了
X
的实例需要位于相等运算符的左侧,成员版本才能工作。如果你想写X x("hello"); string s("hello"); assert(s == x);
您需要一个非会员。
如果您正在实施所有二元关系运算符,那么您的 class 表面积可能会大幅增加。
我通常更喜欢这种辅助界面尽可能与主要 class 逻辑分开(当然,除非您的 class 主要关心的是比较)。
使用非友元免费运算符和最小的 public 界面可能会更好。