运算符在类外重载

bob*_*obo 44 c++ operator-overloading

有两种方法可以为C++类重载运算符:

课内

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 ;
    }
} ;
Run Code Online (Sandbox Code Playgroud)

课外

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 ;
}
Run Code Online (Sandbox Code Playgroud)

(显然在C#中你只能使用"外部类"方法.)

在C++中,哪种方式更正确?哪个更好?

小智 54

基本问题是"您是否希望在操作员的左侧参数上执行转换?" .如果是,请使用免费功能.如果不是,请使用班级成员.

例如,对于operator+()字符串,我们希望执行转换,以便我们可以这样说:

string a = "bar";
string b = "foo" + a;
Run Code Online (Sandbox Code Playgroud)

执行转换以将其char * "foo"转换为std::string.因此,我们将operator+()字符串转换为自由函数.

  • 因此,如果您使用了成员函数版本,那么您可能没有"foo"+ a`,_ _ _ _ _ _ _ _ _ _ _ _ _`````````````````````````````````` (25认同)

小智 16

第一:两种不同的方式实际上是"作为成员重载"和"作为非成员重载",后者有两种不同的方式来编写它(作为朋友内部类定义和外部类定义).称他们为"课堂内"和"课外"会让你感到困惑.


+ =,+, - =, - 等的重载具有特殊模式:

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
Run Code Online (Sandbox Code Playgroud)

此模式允许LHS参数的其他答案中提到的转换,同时大大简化了实现.(成员或非成员允许转换为RHS,当它作为一个const&或一个值传递时,应该如此.)当然,这只适用于你实际上想要超载+ =和+, - =和 - 等等,但这仍然很常见.


此外,你有时要声明的非成员运算+等作为朋友使用类定义中巴顿Nackman诀窍,因为由于模板和超载怪癖,它可能不会被发现,否则.


Fra*_*sco 5

Meyer 的 Effective C++ 中对此问题进行了很好的讨论:第 24 项是“当类型转换应用于所有参数时声明非成员函数”,第 46 项是“需要类型转换时在模板内定义非成员函数”。


归档时间:

查看次数:

51715 次

最近记录:

7 年,6 月 前