他の関数ではあまり使用されない、演算子を記述するときに知っておくべきことがいくつかあります。
たとえば、代入演算子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()
。