[ad_1]
皆さん、こんにちは。
plzz は、演算子のオーバーロードの基本概念を説明してくれますか?
演算子のオーバーロードの使用は何ですか?
なぜ演算子のオーバーロードが必要なのですか?
私はよくグーグルしますが、まだ満足のいく回答を得ていないので、誰かが私を説明するために苦労してください??
ありがとう:)
- 解決策 2
- 概要: 演算子をオーバーライドする場合、基本的には、C++ コンパイラが特定の型の演算子の使用に遭遇したときに特定の関数を呼び出すためのルールを定義します。 演算子の優先順位を再定義できないことに注意してください! 基本的なコア ライブラリ (数学ベクトル/スマート ポインターなど) を作成する場合を除いて、演算子のオーバーロードを使用することはほとんどありません。 基本ライブラリ以外で頻繁に使用する唯一の演算子は代入演算子です。 演算子のオーバーロードは、関数呼び出しを短縮し、基本型の動作を模倣しないために、初心者によって悪用されることがよくあります。
- C++ 演算子のオーバーロードのガイドライン
解決策 2
C++ にはオーバーライド可能な演算子のリストがあることをご存知でしょう。 http://msdn.microsoft.com/en-us/library/5tk49fh2%28v=vs.80%29.aspx[^]. リストを見ると、これらの演算子のほとんどすべてが組み込みのプリミティブ C++ 型 (bool、int、float、pointer) で使用されていることがすぐにわかります。 使用する任意のクラスの演算子を作成できますが、演算子のオーバーロードを使いすぎたり悪用したりするのは非常に簡単です。 作成したクラスが、前述のプリミティブ型のいずれかと同様に機能する場合にのみ使用してください。
– たとえば、3D アプリケーションでは、ベクトル クラスとマトリックス クラスの演算子を定義できます。これは、数値 (int/float) と同じ数学演算子を使用するためです。 これのもう 1 つの良い例は、+ 演算子が文字列の連結に適している文字列クラスです。
– スマート ポインターは、-> 演算子を再定義して、プリミティブな「生の」ポインターを模倣することができます (prefix* および pre/postfix ++ および — 演算子も同様です)。 また、カプセル化された raw ポインター型への変換演算子をいくつか定義したいと考えています。 同じことが、ポインターを模倣してデバッグ機能を追加する C++ イテレーターにも当てはまります。
– ほとんどすべてのクラスで、代入 (=) 演算子を定義して、コピーを定義または無効にする必要があります。
コード例:
struct vec2 { float x, y; vec2(float _x, float _y) : x(_x), y(_y) {} vec2& Add(const vec2& other) { x += other.x; y += other.x; return *this; } vec2& operator+=(const vec2& other) { x += other.x; y += other.x; return *this; } vec2 GetSumWith(const vec2& other) { return vec2(x+other.x, y+other.y); } vec2 operator+(const vec2& other) { return vec2(x+other.x, y+other.y); } vec2& MultiplyWith(float f) { x *= f; y *= f; return *this; } vec2& operator*=(float f) { x *= f; y *= f; return *this; } vec2 GetRightMultiplied(float f) { return vec2(x*f, y*f); } vec2 operator*(float f) { return vec2(x*f, y*f); } }; // When you multiply the vec2 and the float so that the float is on the left you // have to write a global operator* becuase you can not write an operator for // a primitive type like a float. inline vec2 operator*(float f, const vec2& v) { return vec2(f*v.x, f*v.y); } int main(int argc, char* argv[]) { vec2 a(0, 0); vec2 b(1, 1); // All of these are doing the same: a.Add(b); a.operator+=(b); a += b; // All of these are doing the same: vec2 c(a.GetSumWith(b)); vec2 d(a.operator+(b)); vec2 e(a + b); // calling the member vec2*float operator, not that this operator could // also be defined as a global operator. vec2 m = vec2(1, 2) * 5.0f; // calling the global float*vec2 operator vec2 n = 5.0f * vec2(1, 2); return 0; }
例を見て、 Add()
演算子とその main メソッドでの使用により、すぐに気付くことができます。 Add()
と operator+=()
メソッドは同じで、名前だけが異なり、使用できます operator+=()
2 つの方法で: 直接呼び出すか、単に使用して +=
. 一部の演算子はクラス内でのみ定義でき (代入、変換、単項演算子など)、一部はクラスの内外で定義でき (+、-、/ など)、グローバルとしてのみ演算子を記述できる場合もあります。二項演算子の最初のオペランドはあなたのクラスではありません: この例は、フロートによる左マルチプレイでこれを示しています。 演算子は任意のものを返すことができますが、C++ コーダーが通常従う規則がいくつかあることに注意してください。 たとえば、私の operator+=
void を返す可能性がありますが、(something+=something) 式の値は加算の結果であり、私のコードはこのように動作するという規則です。 たとえば、犬と猫のタイプを追加してから牛のタイプを返す演算子を作成できます。
inline cow operator+(const cat& c, const dog& d) { // do the magic and construct a cow from the cat and the dog } // then (ab)using the operator: cat c; dog d; cow(c + d);
上記の例は、演算子のオーバーロードの悪用です。 そのようなことをしなければならない場合は、たとえば次のように関数に名前を付ける必要があります。 CowFromCatAndDog()
. 一部の 3D 数学ライブラリでは、通常は 3 種類のベクトル乗算 (ドット、クロス、コンポーネントごと) があり、乗算は 1 つしかないため、演算子のオーバーロードを悪用します。
C++ の演算子。 これらの操作はすべて名前付きメソッドで使用する必要があると思いますが、多くの場合、これらの操作は C++ 演算子に配置されます: * – ドット、% – クロス。
概要: 演算子をオーバーライドする場合、基本的には、C++ コンパイラが特定の型の演算子の使用に遭遇したときに特定の関数を呼び出すためのルールを定義します。 演算子の優先順位を再定義できないことに注意してください! 基本的なコア ライブラリ (数学ベクトル/スマート ポインターなど) を作成する場合を除いて、演算子のオーバーロードを使用することはほとんどありません。 基本ライブラリ以外で頻繁に使用する唯一の演算子は代入演算子です。 演算子のオーバーロードは、関数呼び出しを短縮し、基本型の動作を模倣しないために、初心者によって悪用されることがよくあります。
解決策 1
1 つの使用法は、演算子のオーバーロードが、計算で使用できる値を表すカスタム クラスでよく使用されることです。 演算子のオーバーロードを使用すると、結果の計算方法を定義できます。 古典的な例の 1 つは、2 つのベクトルの加算です。
あなたが行くべきいくつかのリンク: –[^]
C++ 演算子のオーバーロードのガイドライン
#include<iostream.h> #include<stdio.h> #include<conio.h> class Check { private: float x,y; public: void setData(int a,int b) { x=a; y=b; } void getData() { cout<<"\nx:"<<x<<" y:"<<y; } //Defining an operator function + to overload Check operator +(Check c) { Check temp; temp.x=x+c.x; temp.y=y+c.y; return temp; } //Defining an operator function - to overload Check operator -(Check c) { Check temp; temp.x=x-c.x; temp.y=y-c.y; return temp; } //Defining an operator function * to overload Check operator *(Check c) { Check temp; temp.x=x*c.x; temp.y=y*c.y; return temp; } //Defining an operator function / to overload Check operator /(Check c) { Check temp; temp.x=x/c.x; temp.y=y/c.y; return temp; } }; void main() { clrscr(); Check c1,c2,c3,c4,c5,c6; c1.setData(10,20); c2.setData(15,25); //Overloading operator + c3=c1+c2; c3.getData(); //Overloading operator - c4=c1-c2; c4.getData(); //Overloading operator * c5=c1*c2; c5.getData(); //Overloading operator / c6=c2/c1; c6.getData(); getch(); } Output x:25 y:45 x:-5 y:-5 x:150 y:500 x:1.5 y:1.25
[ad_2]
コメント