Operator overloading outside class
本问题已经有最佳答案,请猛点这里访问。
对于C++类有两种重载运算符的方法:
课堂内1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 ; } } ; |
课外
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 ; } |
(显然,在C中,只能使用"outside class"方法。)
在C++中,哪种方式更正确?哪个更好?
基本问题是"是否希望在运算符的左侧参数上执行转换?"。如果是,请使用自由函数。如果不是,请使用类成员。
例如,对于字符串的
1 2 | string a ="bar"; string b ="foo" + a; |
在执行转换以将
第一:这两种不同的方式实际上是"成员超载"和"非成员超载",后者有两种不同的方式来写它(作为类内定义和类外定义的朋友)。称他们为"班内"和"班外"会让你困惑。
+=、+、-=、-等的重载具有特殊模式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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 |
此模式允许在对lhs参数的其他答案中提到的转换,同时大大简化了实现。(当以
此外,有时您希望使用barton-nackman技巧将非成员op+等声明为类定义中的朋友,因为由于模板和重载的奇怪,因此可能不会找到其他的。
在迈耶的有效C++中有一个很好的讨论:项目24是"当类型转换应该适用于所有参数时声明非成员函数",而项目46是"在需要类型转换时定义模板内的非成员函数"。