3

I am trying to find a simple example program that overloads the following operators of a mathematic vector.

Constructor  // create

= (equals)     // assign

+; -; +=; -=   // add sub

*; /; *=; /=   // multi divide

++; -- // plus minus

==    // compare
>; >=
<; <=

[]    // access a value

Cant seem to find any good simple tutorials. I emphasize the simple because I am only learning this stuff now. If someone could link me or even better program a simple overload for just one of the operators as an example would be incredible!

4

1 に答える 1

10

他の関数ではあまり使用されない、演算子を記述するときに知っておくべきことがいくつかあります。

たとえば、代入演算子return *thisは、ベクトルの値を変更するため、次のようになります。

class v {
public:
  double x_, y_;
  v& operator += (const v& rhs)
  {
     _x += rhs._x;
     _y += rhs._y;
     return *this;
  }
};

もう 1 つの興味深い点は、使用されていないパラメーターだけが原因でpre++と postが異なるということです。++

class v {
public:
  double x_, y_;
  v& operator ++ (); // ++v
  v& operator ++ (int); // v++
};

「等しい」(代入) は、ポインターを使用するときに注意が必要なもう 1 つの問題です。ベクトルの場合、通常は問題になりませんが、ベクトル V を定義してそれ自体に代入する場合は注意が必要です。

class v {
public:
  double x_, y_;
  v& operator = (const v& rhs)
  {
    if(this != &rhs)
    {
      x_ = rhs.x_;
      y_ = rhs.y_;
    }
    return *this;
  }
};

あなたの場合、if()おそらく役に立たないでしょうが、次のようなことを考えてみてください:

   delete p_;
   p_ = new foo;
   p_->x_ = rhs.p_->x_;

の場合&rhs == thisは、ポインターをdelete p_削除しました。rhsつまり、3行目でアクセスするのはバグです。

残りは簡単に操作できるはずです。比較演算子は次のboolとおりconstです。

class v {
public:
  double x_, y_;
  bool operator == (const v& rhs) const
  {
    return x_ == rhs.x_ && y_ == rhs.y_;
  }
};

ただし、C++20 以降<=>では、コンパイラが他のすべての比較演算子を実装できるようにする 3 方向比較演算子のみを宣言する必要があります。これは、負の数 (小さい方: a < b)、0 (等しい: a == b)、または正の数 (大きい方: a > b) を返します。

ベクトルを大きくしたり小さくしたりする理由がわかりません。この例では (0, 0) からの長さを使用しました。

class v {
public:
  double x_, y_;
  int operator <=> (const v& rhs) const
  {
    if(x_ == rhs.x_ && y_ == rhs.y_)
    {
      return 0;
    }
    return length() > rhs.length() ? 1 : -1;
  }
};

[]オペレーター以外。そのバージョンには 2 つのバージョンがあります。

class v {
public:
  // I would imagine you'd use an array but as a simple example...
  double x_, y_;
  double operator [] (int idx) const
  {
    return idx == 0 ? x_ : y_;
  }
  v_ref operator [] (int idx)
  {
    v_ref v(this, idx);
    return v;
  }
};

ご覧のとおり、[] 演算子の非定数バージョンは参照を返します。これは、次のように記述できるようにするために必要です。

r[3] = 7.3;

r[3]その参照を返すと、参照の代入が7.3パラメータとして呼び出されます。(0 と 1 の 2 つの値しかない場合にインデックスとして 3 を使用すると、おそらくエラーが発生することに注意してください。これはここには示されていません)。

class v_ref
{
public:
  v *p_;
  int i_;
  v_ref(v *p, int i)
    : p_(p), i_(i)
  {
  }
  operator = (double q)
  {
     // again, I suppose you'd use an array instead!
     if(i_ == 0)
     {
       p_->x_ = q;
     }
     else
     {
       p_->y_ = q;
     }
  }
};

ある程度のセキュリティが必要であると仮定すると、ベクトル ポインターは参照カウンターを利用できるため、すべての参照オブジェクトの前にメインのベクトル オブジェクトが削除されるかどうかがわかります...

別の注意: コンストラクターが double の配列を割り当てる (またはstd::vector<double>型を使用する)と想像しますif()

于 2013-10-31T02:55:29.757 に答える