15

以下の C++ プログラムが "ACCA" を出力するのはなぜですか? operator int()が2 回呼び出されるのはなぜですか?

#include "stdafx.h"
#include <iostream>

using namespace std;

class Base {
public:
    Base(int m_var=1):i(m_var){
        cout<<"A";
    }
    Base(Base& Base){
        cout<<"B";
        i=Base.i;
    }
    operator int() {
        cout<<"C";
        return i;
    }
private:
    int i;
};

int main()
{
    Base obj;
    obj = obj+obj;
    return 0;
}
4

9 に答える 9

30

まず、この行:

Base obj;

objデフォルト値を持つ整数を受け入れるコンストラクターを選択することにより、オブジェクトをデフォルト構築します1Aこれは、最初に標準出力に出力される責任があります。

次に、この表現:

obj + obj

の実行可能なオーバーロードを選択する必要がありoperator +ます。この場合、 にobjは へのユーザー定義の変換があるためint、ビルトインoperator +が選択され、両方の引数が に変換されintます。これにより、2 つCの が標準出力に出力されます。

次に、への割り当てobj:

obj = obj + obj

暗黙的に生成されたoperator =forを呼び出す必要がありBaseます。暗黙的に生成されoperator =た署名があります:

Base& operator = (Base const&);

これは、等号の右側にある 型の式を、割り当て元の一時オブジェクトintに変換する必要があることを意味します (暗黙的に生成された の参照パラメーターは、この一時オブジェクトにバインドされます)。Baseobjoperator =

しかし、 an からこの一時的なものを作成するには、 an を受け入れるint変換構造を呼び出す必要があります。これは、標準出力に出力される秒を担当します。BaseintA

于 2013-06-11T16:40:51.630 に答える
9

operator int()をオーバーロードしていないため、 が 2 回呼び出されますoperator+Baseコンパイラは aを aに追加する方法を知らないため、 (その方法を教えたので) にBase変換されますが、その方法はわかっています。int次のコードは次のように表示されますADA

#include <iostream>

using namespace std;

class Base {
public:
    Base(int m_var=1):i(m_var){
        cout<<"A";
    }
    Base(Base& Base){
        cout<<"B";
        i=Base.i;
    }
    operator int() {
        cout<<"C";
        return i;
    }
    int operator+(Base& Base)
    {
        cout<<"D";
        return i+Base.i;
    }
private:
    int i;
};

int main()
{
    Base obj;
    obj = obj+obj;
    return 0;
}
于 2013-06-11T16:39:39.587 に答える
5

オブジェクトを構築すると、最初の「A」が得られます。

 Base obj;

add を指定するobj+objと、コンパイラは+onを使用する方法を見つける必要がありますobj。for をオーバーライドしなかったoperator+ため、式の各辺に対してBaseへの変換が呼び出されます。int()

obj+obj

これは印刷され"CC"ます。

次に、obj型のに代入するため、(演算子からの) Baseint を受け入れることができるコンストラクターが実行され、"A" が出力されます。i + iint()

obj = obj+obj; // Assignment prints "A"
于 2013-06-11T16:40:45.880 に答える
5
obj = obj+obj;
      ^^^--------obj converted to int here
          ^^^----obj converted to int here
^^^^^------------Base(int) ctor and default operator= called here

キャスト演算子をオーバーロードすることは、コストを理解し、特定のケースでの利点がそれらを上回るという事実を知っていない限り、一般的には良い考えではありません。

于 2013-06-11T16:42:13.237 に答える
1

式で obj を 2 回参照し、obj+objそのような各参照を整数に変換する必要があります。

そのような変換が「ステートフル」である可能性は (恐ろしい考えですが) 不可能ではありません。つまり、呼び出されるたびに異なる値を返すように設計されている可能性があります。結局、 によって表される値objは変更される可能性があります (カウンターなどである可能性があります)。そのため、コンパイラは参照ごとにそれを新たに評価する必要があります。

于 2013-06-11T16:40:18.800 に答える
1

オペランドごとに 1 回呼び出されます。同じインスタンスであるかどうかは問題ではありません。

 obj = obj+obj;

最初のオペランドを int に "キャスト" し、次に 2 番目のオペランドを "キャスト" します。

この暗黙のキャストを避けたい場合は、演算子 + をオーバーロードする必要があります。

于 2013-06-11T16:40:19.707 に答える
1

operator int()追加する前に両方の obj を int に変換する必要があるため、2 回呼び出します。

于 2013-06-11T16:40:40.957 に答える
1

最初の A は

Base obj;

2 つの Cobj+objintoperator +.

最後の A は、結果を にobj =変換したものです。intobj

于 2013-06-11T16:44:38.990 に答える