2
struct PT 
{   
  double x, y;  
  PT() {}  
  PT(double x, double y) : x(x), y(y) {}  
  PT(const PT &p) : x(p.x), y(p.y)    {}  
  PT operator + (const PT &p)  const { return PT(x+p.x, y+p.y); }  
  PT operator - (const PT &p)  const { return PT(x-p.x, y-p.y); }  
  PT operator * (double c)     const { return PT(x*c,   y*c  ); }  
  PT operator / (double c)     const { return PT(x/c,   y/c  ); }  
};

このコード スニペットはhttp://stanford.edu/~liszt90/acm/notebook.html#file8からのものです。このコードが理解できません。誰かこれを説明してください。これが演算子のオーバーロードであることは知っていますが、演算子のオーバーロードがどのように行われているかを正確に理解することはできません。

誰かがこれらの行も説明できますか:

PT() {}  
PT(double x, double y) : x(x), y(y) {}  
PT(const PT &p) : x(p.x), y(p.y)    {}

構造体にもコンストラクターがありますか?

4

5 に答える 5

2
double x, y;  

クラスを構成する 2 つのローカル クラス変数を宣言します。

PT() {}  

デフォルトのコンストラクタ。引数なしで PT を作成できます。
例 --> PT myObj;

PT(double x, double y) : x(x), y(y) {}  

2 つの double からポイントを作成するコンストラクター。
例 --> PT myObj(3.5, 9.0);
宣言の後 --> PT(double x, double y) : x(x), y(y) {}
初期化があります .--> PT(double x, double y) : x(x) , y(y) {} は 、クラス変数 'x' をコンストラクター パラメーター 'x' で初期化
x(x)することと同等です。this->x = x;
パラメータにクラス変数と同じ名前を付けているのはやや混乱します。より良い例は次のとおりです。

    PT(double xInit, double yInit) 
    : x(xInit)
    , y(yInit) 
    {
    }  



    PT(const PT &p) : x(p.x), y(p.y)    {}  

コンストラクターをコピーして、別の PT オブジェクトから PT オブジェクトを作成します。
例: --> PT myOtherObj(myObj);

PT operator + (const PT &p)  const { return PT(x+p.x, y+p.y); }  
PT operator - (const PT &p)  const { return PT(x-p.x, y-p.y); }

2 つのポイントの合計または差を取得して 3 番目のポイントを作成する加算および減算演算子。
例 -->

    PT sumObj  = myObj + myOtherObj;
    PT diffObj = myObj - myOtherObj;



PT operator * (double c) const { return PT(x*c, y*c ); }
PT operator / (double c) const { return PT(x/c, y/c ); }

ポイントを定数で乗算 (または除算) するための乗算および除算演算子。
例 -->

    PT prodObj = myObj * 2.7;
    PT divObj  = myObj / 8.0;
于 2012-06-16T06:49:59.180 に答える
1

4 行目と 5 行目はconstructorsであり、構文x(x)はメンバー変数のコンストラクターを呼び出す慣用的な方法を強調しています (つまり、下に渡す)。

仮パラメータに別の識別子は必要ないことに注意してください。正式なパラメーターがメンバー変数を「隠す」ため、コンストラクターの本体内からの割り当てには別の名前が必要です。つまり、たとえば、必要になります

 PT(double x_, double y_) { x = x_; y = y_; }  

また、この方法でメンバー x のコンストラクターを呼び出すのではなく、代入演算子を呼び出すことに注意してください。POD データには違いはありませんが、構文では、 のようなクラスで任意のユーザー定義のメンバー関数を使用できますPT

于 2012-06-16T06:32:02.150 に答える
0

おそらく、非メンバーバージョンを見ると、演算子のオーバーロードを理解しやすくなります。2つのオブジェクトを追加してコンパイラに何を意味するのかを伝えたい場合はPT、次のように記述できます。

PT operator + (const PT& a, const PT& b)
{
    return PT(a.x + b.x, a.y + b.y);
}

上記のコードは、コンパイラがとのa + b両方がインスタンスである式を見つけると、結果はその関数によって計算された新しいインスタンスになることを単に示しています。abPTPT

他のいくつかの演算子についても同じことができます。これにより、クラスインスタンスを通常の数学に対してより「自然に」動作させることができます。

あなたが持っているコードは同じですが、たとえば別のオブジェクトがオブジェクトに追加されたときに何をすべきかを説明する、やや不自然な非対称形式で書かれていthisます。このようなアプローチは、バイナリ数学演算子では非常に奇妙に見えます。たとえば、加算の第1オペランドまたは第2オペランドには特別なものはなく、両方とも同じ論理レベルにあるためです。ただし、この概念の非対称性thisはC ++ DNAの一部であり、それについてできることはほとんどありません。理論的には、パラメータだけを使用するメソッドにとっては悪い非対称性ですが、実際には、このアプローチを使用してもかなりの期間を実行できます。

コードの他の部分は次のとおりです。

// Default constructor. Will create an object without any parameter
// and the x, y values will be uninitialized. This is generally a bad
// practice and you should avoid it unless there are very specific and
// measured performance reasons for doing that.
// Having a constructor accepting no parameters is sometimes necessary
// if you want for example to be able to put your instances in an std::vector
// and you may need to call .resize() on the vector. Even if you will always
// just shrink the vector the compiler will require anyway a default
// constructor because there's no shrink-only call on vectors and any
// resize operation is assumed to be potentially growing the size.
PT() {}

// Copy constructor. This is totally unneeded... when you don't
// put a copy constructor in a class the C++ compiler will automatically
// generate exactly this code (i.e. a constructor that will copy-construct
// all members). In general this may be or may not be the right thing
// depending on the class, but in this case is exactly what you want
// and there was no need for this code.
// As a general rule if you see a copy constructor, an assignment operator
// or a destructor but you don't see all three of them in a class then
// most probably there's something wrong. It's difficult to think to
// a real use case in which you need some of them but not all three of
// them... in this case for example the mistake is that this code could
// and should have been omitted.
PT(const PT &p) : x(p.x), y(p.y) {}
于 2012-06-16T06:11:03.833 に答える
0

コンパイラが次の形式の呼び出しに遭遇するたびに

a + b;

それは実際に呼び出します

a.operator+(b)

そのようなメソッドが a またはの型に存在する場合

operator+(a,b)

そのような自由な機能が存在する場合。

オペレーター???構文は、現在、上記の演算子をオーバーロードしていると言っているだけです??? (もちろん、有効な???の場合)。

于 2012-06-16T05:56:02.220 に答える
0

演算子のオーバーロードは、+、 '- , '*、... などの通常の演算子が構造体/クラスに対しても「オーバーロード」される概念です。int通常、この機能は、double、 ...などの元のデータ型でのみ使用できます。

ここでstruct PT、演算子メソッドは単純に定義されています。オブジェクトを宣言してPT使用を開始すると、開始されます。例えば

PT pt1, pt2;
PT pt3 = pt1 + pt2;  // pt1.operator +() has instantiated
于 2012-06-16T05:56:56.133 に答える