複素数のクラスを作成し、操作を定義し、arg や係数などの関数を定義しました。また、虚数単位iを名前空間の定数として定義しました。問題は、z = i + 2
エラーを返さず、正しく動作することですが、コンパイラは、と の間でz = 2 + i
オペランドが無効であるという行を受け入れません。int
const complex
操作を両方の方法で定義するにはどうすればよいですか?
複素数のクラスを作成し、操作を定義し、arg や係数などの関数を定義しました。また、虚数単位iを名前空間の定数として定義しました。問題は、z = i + 2
エラーを返さず、正しく動作することですが、コンパイラは、と の間でz = 2 + i
オペランドが無効であるという行を受け入れません。int
const complex
操作を両方の方法で定義するにはどうすればよいですか?
整数と複素数の間の変換を実装するか、両方の演算子を定義する必要があります。
complex operator+(int a, const complex& b)
と
complex operator+(const complex& a, int b)
クラスをオーバーロードする必要がありcomplex operator+(int lhs, const complex& rhs);
ます。これをfriend
関数にして、両方のパラメーターを渡します。
演算子に実数および複素数のオーバーロードを提供する代わりに:complex
クラスに変換コンストラクター (マークされておらずexplicit
、単一のパラメーターを受け取ることができるコンストラクター) を指定すると、実数を暗黙的に複素数に変換できます。
class complex
{
public:
complex(double real, double imag = 0) : real_(real), imag_(imag) {}
double real() const { return real_; }
double imag() const { return imag_; }
private:
double real_;
double imag_;
};
operator+
次に、 2 つのパラメーターを取るように定義するcomplex
と、コンパイラーが を に変換int
しcomplex
ます。
complex operator+(const complex& a, const complex& b)
{
return complex(a.real() + b.real(), a.imag() + b.imag());
}
これで、コンパイラはこのコードに遭遇すると、 のcomplex, complex
オーバーロードがoperator+
存在し、2
暗黙的に に変換できることを認識しcomplex
ます。
z = 2 + i;
クラスの演算子をオーバーロードする方法は2つあります。メンバー関数としてと...非メンバー関数です。最初のオブジェクトはComplex
、演算子(+
この場合)の左側にクラスのオブジェクト(この場合はクラス)がある場合に作成されます。上記が発生しない場合は、非会員機能を使用します。この場合、両方のオペランドが指定され、オーバーロードされた演算子自体は、フレンドアクセスを使用してクラス内で誤って(場合によっては)作成されるだけです(実際、プライベートメンバーにアクセスしない場合は必要ありません。クラスとは、このようにして、特定のクラスの演算子が同じ場所にあることです)。
class Complex {
public:
// more things...
Complex operator+(int i); // cx + 1
friend Complex operator+(int i, const Complex &cx); // 1 + cx
// more things...
};
Complex Complex::operator+(int i)
{
Complex complexCopy( *this );
complexCopy.sum( i );
return complexCopy;
}
Complex operator+(int i, const Complex &cx)
{
Complex complexCopy( cx );
complexCopy.sum( i );
return complexCopy;
}
コンストラクターにリソースを割り当てる場合に備えて、コピーコンストラクターをオーバーロードする必要があることに注意してください。
お役に立てれば。
の演算子のオーバーロードを処理する良い方法+
は、 から始めること+=
です。
class complex {
double real
double imag;
complex& operator+=( complex const& other ) {
real += other.real;
imag += other.imag;
return *this;
}
complex& operator+=( double other ) {
real += other.real;
return *this;
}
};
次に、上記のメンバー演算子を使用する非メンバー演算子を記述します。
inline complex operator+( complex left, double right ) {
return left+=right;
}
inline complex operator+( double left, complex right ) {
return right+=left;
}
inline complex operator+( complex left, complex const& right ) {
return left+=right;
}
少なくとも 1 つのcomplex
引数を値で受け取ったことに注意してくださいcomplex
。数値を返すことを考えると、そうする場合もあります。
この計画の良いところは、二項演算子が実際のボイラープレートであり、メンバー+=
演算子で作業が行われることです。
C++11 では、さらに一歩進んで、上記のすべての演算子を自動記述し、さまざまなオーバーロードに基づいて有効な型を抽出できますoperator+=
。しかし、これは、オーバーロードするクラスをたくさん書いている場合にのみ価値があります+
。