1

コンストラクターと割り当てを理解するために、次のような非常に単純なテスト コードを作成しました。

class A {
public:
    A() { std::cout<<"This is default cstr."; }
    A(int i) { std::cout<<"This is int cstr. value is "<<i; }
    A(const A &a) { std::cout<<"This is copy cstr."; }
    A operator=(const A &a) { std::cout<<"This is assignment operator."; return *this;// this line is tricky }
};
int _tmain(int argc, _TCHAR* argv[]) {
    std::cout<<"line 1 "; A a1; std::cout<<std::endl;
    std::cout<<"line 2 "; A a2 = A(1); std::cout<<std::endl;
    std::cout<<"line 3 "; a1 = a2; std::cout<<std::endl;
    return 0;
}

3行目で得たもの:

line 3 This is assignment operator.This is copy cstr.

しかし、に変更return *this;するとreturn NULL、次のようになりました。

line 3 This is assignment operator.This is int cstr. value is 0

誰かが私のために何が起こったのか説明できますか?

4

3 に答える 3

1

問題

line 3 This is assignment operator.This is copy cstr.

あなたのコードの呼び出し:

A operator=(const A &a) { std::cout<<"This is assignment operator."; return *this;

これは明らかに「これは代入演算子です。」と出力し、return *this;ステートメントは戻り値の型を見て、-> と同等の動作をするA型の戻り値を作成し、コピー コンストラクターを呼び出して、出力のこの部分を説明します。AA(*this);

line 3 This is assignment operator.This is copy cstr.
                                   ^^^^^^^^^^^^^^^^^^

しかし、return *this; を変更すると、NULLを返すために、私は得ました:

line 3 This is assignment operator.This is int cstr. value is 0

この場合:

A operator=(const A &a) { std::cout<<"This is assignment operator."; return NULL; }

最終的に type の戻り値をAごとA(NULL)に作成し、NULL は 0 であるため、A(int)コンストラクターに最もよく一致します。これが次の理由です。

line 3 This is assignment operator.This is int cstr. value is 0
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

ソリューション

A& operator=(const A &a) { std::cout<<"This is assignment operator."; return *this; }
 ^

通常、代入演算子はオブジェクトへの参照を返す必要があり*thisます。Aそうすれば、代入演算子関数が戻るときに追加のオブジェクトが構築されることはありません。

余談ですが、なぜ `A&` を返すのでしょうか?

A&ではなく が返される理由はvoid、次のように、オブジェクトをさらに連鎖して使用できるためです。

a1 = a2 = a3;

次のように評価されます。

a1.operator=(a2.operator=(a3));

a2.operator=返さvoidれた場合、 への使用可能な引数はありませんa1.operator=()

const参照は、次のような使用法をサポートします。

make_uppercase(my_string = other_string);

他の言語では、これを 2 つのステートメントに分割する必要があります。あなたがそれを望んでいたかどうかは、あなたがそれを混乱させるかどうか、そして簡潔さをどれだけ重視するかによって異なります.

于 2013-10-30T02:32:11.490 に答える
1

あなたのオペレーターはA代わりに戻ってきますA&:

A operator=(const A &a)

したがって、 を返すときNULLは、暗黙のコンストラクターを呼び出してそれA(int)に渡しNULLます。

于 2013-10-30T02:23:07.477 に答える
0

あなたのコードは言う

A operator = (const A& a)

A への参照を取得し、自分自身を変更してから A(*this) を返します。これにより、コピー コンストラクターが呼び出されて新しいインスタンスが作成され、値が返されます。

おそらくあなたが意図したのは

A& operator = (const A& a)

これにより、参照が返さ*thisれ、新しい一時インスタンスにコピーする必要がなくなります。

NULL は、コンパイラが A(int) に一致するものとして検出する '0UL' または '0ULL' のマクロ エイリアスであることに注意してください。nullptrこれが、C++11が NULL の代替として導入された理由の 1 つです。

于 2013-10-30T02:28:11.703 に答える