0

私は以下のコードを持っています

class rectangle
{
    //Some code ...
    int operator+ (rectangle r1)
    {
        return(r1.length + length);//Length is the 1st argument of r1, r2, r3
    }
};

主な機能で

int main()
{
    rectangle r1(10,20);
    rectangle r2(40,60);
    rectangle r3(30,60);
    int len = r1 + r3;
}

ここで見るとoperator+()、やっていr1.length + lengthます。コンパイラは、returnステートメントの2番目がオブジェクトにlength属していることをどのようにして知るようになりますか?答えは私たちが書いたものかもしれないと思いますr3r1r2main()

int len = r1 + r3;

その場合、なぜ私たちは書く必要があるのですか?

operator+ (....) 
{
    r1.lenth + lenth; //Why not length + length?
}

どうしてlength + lengthmain()コンパイラは、それからに属していることとにfirst length属していることをすでに知っているからです。object r12ndobject r3

4

6 に答える 6

5

変数名と引数名を混同しています。演算子のオーバーロードで、パラメーターに次の名前を付けましたr1

int operator+(rectangle r1)
{
   return(r1.length+length);
}

つまり、渡すパラメータが何であれoperator +、演算子の本体内でr1(元の名前に関係なく)名前が付けられます。

r1.lengthはパラメータlengthの長さであり、は現在のオブジェクトの長さです(つまりthis->length)。

//長さ+長さではないのはなぜですか?

これは、現在のオブジェクトの長さの2倍を返すだけです。

コードを分析してみましょう:

rectangle r1(10,20);
rectangle r2(40,60);
rectangle r3(30,60);
int len = r1+r3;

最後の呼び出しは。と同等r1.operator+(r3)です。演算子の内部では、lengthを表しr1.length、をr1.length表しr3.lengthます。実際には、r3.length値を渡すので、コピーが作成されます。通常の構文は次のとおりです。

int operator+(const rectangle& r1)
{
   return(r1.length+length);
}

また、長方形を追加することは、少なくともそれをどのように定義したかでは、実際には意味がありません。2つの長方形を追加すると、長さの合計が返されることは直感的ではありません。少なくとも別の形を返す必要があります。

于 2012-10-01T09:36:25.537 に答える
2

オブジェクト内の各変数は、別のオブジェクトの変数とは異なります。コンパイラは、パラメータを介してオブジェクトを渡すかどうかだけを認識します。それを知る他の手段はありません。関数を呼び出すと、オブジェクトのコピーがスタックに作成されます。パラメーター・リストで指定した名前は、関数を呼び出したときに使用した名前に関係なく、コンパイラーが使用する名前になります。

int operator+(rectangle r1)
    {
        return(r1.length+length);
    }

r1 + r3; //In main

この例では、関数呼び出しでのオブジェクトの名前はですr1。何でも名前を付けることができます。コンパイラは、その名前がr3mainで呼び出されたときのものであることを認識していません。そして、関数から整数を返しています。一時オブジェクトを作成し、値で返す方がよいでしょう。

于 2012-10-01T09:36:56.953 に答える
2

int len = r1 + r3;

これは解決されます

int len = r1.operator+(r3);

したがって、メソッドはr1オブジェクトで呼び出され、operator+のメンバーへの参照はのメンバーにr1なり、r3はそのメソッドの実際の引数になります。

于 2012-10-01T09:37:35.150 に答える
1

コンパイラーは、長方形の長さメンバー変数、、を。から区別する必要がありthis->lengthますr1.length。書き込みlength + lengthは、ローカルスコープの変数がthis->length加算の両側で使用されることを意味します。

于 2012-10-01T09:36:44.240 に答える
1

演算子はのメンバー関数に似ていますclass rectangleが、別の呼び出し形式を使用します。

int len = r1.operator+(r3);他のユーザーが提案した関数として呼び出すこともできます。

したがって、クラスの演算子を使用して操作を作成すると、コンパイラーはその呼び出しを指定された演算子の一部と一致させようとします。あなたの電話で:

int len = r1+r3;

コンパイラーは、operator+に入れることができるものを返し、パラメーターとしてaintを受け取るものを探し、関数を見つけました。次に、パラメータを使用してこの関数を呼び出し、結果を返します。rectangleint operator+(rectangle r1)r3int

int operator+(rectangle r1)関数に指定されたパラメーターはsoのコピーであるr3ため、またはで動作しているのではr3なく、動作しているのはそのためです。r1r2

これは質問では言及されていませんが、言及する価値があると思います:

演算子が通常従うモデルには適してoperator+いないようです。を追加して操作とはrectangle異なるオブジェクトを取得する場合rectangle、演算子のようには見えません。何を手に入れたいのか、sの総和とは何かを考えなければならないと思いますrectangle

二項演算子として、通常は同じ種類のオブジェクトを取得して返します(操作チェーンで使用するため)。オブジェクト自体は変更されないため、constである必要があります。

class rectangle
{
    // Reference in order to avoid copy and const because we aren't going to modify it.
    // Returns a rectangle, so it can be used on operations chain.
    rectangle operator+(const rectangle &r) const
    {
        rectangle Result;
        // Do wathever you think that must be the addition of two rectangles and...
        return Result;
    }
};

int main()
{
    rectangle r1(10,20);
    rectangle r2(40,60);
    rectangle r3 = r1 + r2;
    // Operation chain
    rectangle r4 = r1 + r2 + r3;
    rectangle r5 = r1 + r2 + r3 + r4;

    // Is this what you're looking for?
    int width = (r1 + r3).width();
    int height = (r1 + r3).height();
}

単項演算子の場合、パラメーターと戻り値も同じタイプである必要がありますが、戻り値は操作の一部となるオブジェクトである必要があります。

class rectangle
{
    // Reference in order to avoid copy and const because we aren't going to modify it.
    // Returns a rectangle, so it can be used on operations chain.
    rectangle &operator+=(const rectangle &r) const
    {
        // Do wathever you think that must be the addition of two rectangles and...
        return *this;
    }
};

int main()
{
    rectangle r1(10,20);
    rectangle r2(40,60);
    rectangle r3 = r1 + r2;
    // Weird operation chain, but it's only an example.
    rectangle r4 = (r1 += r2) += r3;
    rectangle r5 = (r1 += r2) += (r3 += r4);
}
于 2012-10-01T10:37:43.483 に答える
0

演算子のオーバーロードは、通常の関数呼び出し以上/以上機能します。

と考えてa+bくださいa.operator+(b)

奇妙な名前は別として、その呼び出しには。との違いはありませんa.add(b)

関数のaddシグネチャがint A::add(A x)(Aがクラスの場合)の場合、bはxにコピーされ、-inside addbody-xとaのすべてのメンバーにアクセスできます。

しかし、これは演算子にとって特別なことではありません。これは、パラメーターの受け渡し(C ++のデフォルトは「コピーによる」)変数のスコープと可視性に関連しています。

それを理解できれば、演算子のオーバーロードが明らかになるはずです。できない場合は、「関数、メンバー関数、およびパラメーター」に戻り、それらの概念が明確になるまでそこから離れないでください。

于 2012-10-01T10:11:30.100 に答える