c++ overloaded 運算符在類外重載




operator overloading c++ struct (3)

這個問題在這裡已有答案:

有兩種方法可以為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 ;
    }
} ;

課外

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#中你只能使用“外部類”方法。)

在C ++中,哪種方式更正確? 哪個更好?


基本問題是“您是否希望在操作員的左側參數上執行轉換?” 。 如果是,請使用免費功能。 如果不是,請使用班級成員。

例如,對於字符串的operator+() ,我們希望執行轉換,以便我們可以這樣說:

string a = "bar";
string b = "foo" + a;

執行轉換以將char * "foo"轉換為std::string 。 因此,我們將字符串的operator+()變為自由函數。


在Meyer的Effective C ++中對這個問題進行了很好的討論:第24項是“當類型轉換應該應用於所有參數時聲明非成員函數”,第46項是“當需要類型轉換時在模板內定義非成員函數”。


第一:兩種不同的方式實際上是“作為成員重載”和“作為非成員重載”,後者有兩種不同的方式來編寫它(作為朋友內部類定義和外部類定義)。 稱他們為“課堂內”和“課外”會讓你感到困惑。

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

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參數的其他答案中提到的轉換,同時大大簡化了實現。 (成員或非成員允許轉換為RHS,當它作為const&或值傳遞時,應該如此。)當然,這僅適用於實際上想要重載+ =和+, - = - 等等,但這仍然很常見。

此外,您有時希望使用en.wikipedia.org/wiki/Barton-Nackman_trick將非成員op +等聲明為類定義中的codepad.org/ACNeZcCf ,因為由於模板和重載的怪癖,可能無法找到它。





operator-overloading