C++ 操作符在类外重载
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2425906/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Operator overloading outside class
提问by bobobobo
There are two ways to overload operators for a C++ class:
有两种方法可以为 C++ 类重载运算符:
Inside class
内课
class Vector2
{
public:
float x, y ;
Vector2 operator+( const Vector2 & other )
{
Vector2 ans ;
ans.x = x + other.x ;
ans.y = y + other.y ;
return ans ;
}
} ;
Outside class
课外
class Vector2
{
public:
float x, y ;
} ;
Vector2 operator+( const Vector2& v1, const Vector2& v2 )
{
Vector2 ans ;
ans.x = v1.x + v2.x ;
ans.y = v1.y + v2.y ;
return ans ;
}
(Apparently in C# you can only use the "outside class" method.)
(显然在 C# 中,您只能使用“外部类”方法。)
In C++, which way is more correct? Which is preferable?
在 C++ 中,哪种方式更正确?哪个更可取?
回答by
The basic question is "Do you want conversions to be performed on the left-hand side parameter of an operator?". If yes, use a free function. If no, use a class member.
基本问题是“您是否希望对运算符的左侧参数执行转换?” . 如果是,请使用免费功能。如果不是,请使用类成员。
For example, for operator+()
for strings, we want conversions to be performed so we can say things like:
例如,对于operator+()
字符串,我们希望执行转换,以便我们可以这样说:
string a = "bar";
string b = "foo" + a;
where a conversion is performed to turn the char * "foo"
into an std::string
. So, we make operator+()
for strings into a free function.
其中执行转换以转char * "foo"
成std::string
。所以,我们把operator+()
字符串变成了一个自由函数。
回答by bobobobo
First: the two different ways are really "overload as a member" and "overload as a non-member", and the latter has two different ways to write it (as-friend-inside class definition and outside class definition). Calling them "inside class" and "outside class" is going to confuse you.
第一:两种不同的方式实际上是“作为成员重载”和“作为非成员重载”,后者有两种不同的写法(as-friend-inside class definition and outside class definition)。称他们为“班内”和“班外”会让你感到困惑。
Overloads for +=, +, -=, -, etc. have a special pattern:
+=、+、-=、- 等的重载有一个特殊的模式:
struct Vector2 {
float x, y;
Vector2& operator+=(Vector2 const& other) {
x += other.x;
y += other.y;
return *this;
}
Vector2& operator-=(Vector2 const& other) {
x -= other.x;
y -= other.y;
return *this;
}
};
Vector2 operator+(Vector2 a, Vector2 const& b) {
// note 'a' is passed by value and thus copied
a += b;
return a;
}
Vector2 operator-(Vector2 a, Vector2 const& b) { return a -= b; } // compact
This pattern allows the conversions mentioned in the other answers for the LHS argument while simplifying the implementation considerably. (Either member or non-member allows conversions for the RHS when it's passed either as a const&
or by value, as it should be.) Of course, this only applies when you do actually want to overload both += and +, -= and -, etc., but that is still common.
这种模式允许 LHS 参数的其他答案中提到的转换,同时大大简化了实现。(当 RHS 以 aconst&
或按值传递时,成员或非成员都允许对 RHS 进行转换,这应该是。)当然,这仅适用于您确实想要重载 += 和 +、-= 和- 等,但这仍然很常见。
Additionally, you sometimes want to declare your non-member op+, etc. as friendswithin the class definition using the Barton-Nackman trick, because due to quirks of templates and overloading, it may not be found otherwise.
此外,你有时要声明的非成员运算+等作为朋友使用类定义中巴顿Nackman诀窍,因为由于模板和重载怪癖,它可能不会被发现,否则。
回答by Francesco
There is an excellent discussion of this issue in Meyer's Effective C++: Item 24 is "Declare non-member functions when type conversions should apply to all parameters" and Item 46 is "Define non-member functions inside templates when type conversions are desired".
Meyer 的 Effective C++ 中对此问题进行了很好的讨论:第 24 项是“当类型转换应用于所有参数时声明非成员函数”,第 46 项是“需要类型转换时在模板内定义非成员函数”。