2

以下のプログラムはx=10 y=0を出力します

#include<iostream>
using namespace std;

class Test
{
private:
  int x;
  int y;
public:
  Test (int x = 0, int y = 0) { this->x = x; this->y = y; }
  Test setX(int a) { x = a; return *this; }
  Test setY(int b) { y = b; return *this; }
  void print() { cout << "x = " << x << " y = " << y << endl; }
};

int main()
{
  Test obj1;
  obj1.setX(10).setY(20);
  obj1.print();
  return 0;
}

しかし、私たちが置き換える場合

Test setX(int a) { x = a; return *this; }
Test setY(int b) { y = b; return *this; }

Test &setX(int a) { x = a; return *this; }
Test &setY(int b) { y = b; return *this; }

出力はx=10 y = 20です。なぜこれが起こっているのか誰かが説明できますか?

4

5 に答える 5

4

参照ではなくプレーンオブジェクトを返す場合は、メソッドを呼び出したオブジェクトのコピーを返します。setYそのコピー(一時的なもの)に作用すると、コピーは破棄されます。

参照を返すと、すべての呼び出しが同じオブジェクトで動作するため、探している動作が得られます。

于 2012-09-15T13:34:56.493 に答える
2

の最初の呼び出しはの一時的なコピーsetX()返し、の呼び出しは一時的なものを変更します。の状態を表示する後続の呼び出しは、メンバー変数が変更されていないため、ゼロのままです。obj1setY()print()obj1obj1y

戻り値の型を参照に置き換えると、への呼び出しsetX()setY()操作の両方で一時的なコピーは作成されませんobj

于 2012-09-15T13:35:04.077 に答える
1

オブジェクト指向プログラミングの基礎に戻りましょう。

比喩を使ってみましょう-バスと言います。

バスには、変更可能な特定のプロパティがあります(燃料など)。

したがって、機能(燃料を補充する)がある場合は、燃料タンクがいっぱいになっている最後の1ビットとまったく同じ新しいバスは必要ありません。

では、元の質問に戻ります。

Test setX(int a) { x = a; return *this; }

読む必要があります

void setX(int a) { x = a; }

あなたは同じオブジェクトを持っていますが、燃料が補充される可能性があります(この場合はx)

于 2012-09-15T13:54:41.470 に答える
0

最初のケースでは、オブジェクトを値で返します。したがって、オブジェクトのコピーが作成されて返されます。したがって、
obj1.setX(10)はテストのコピーを返し、.setY(20)はそのコピーで機能するため、その効果はobj1にはありません。
2番目のケースでは、オブジェクトへの参照が返されるため、.setY(20)はobj1自体で機能します。したがって、出力。

于 2015-07-17T06:42:18.863 に答える
-1

このピンターにはオブジェクトのアドレスが含まれています。最初の場合、setx funでは、このポインターはxを返し、同時にy値を返すことはできません。したがって、yのアドレスではなくyのコピーを送信します。2番目のケースでは、この両方の関数は異なり、両方ともこのポインターを所有しているため、xとyの両方のアドレスを送信します

于 2022-01-13T10:04:57.533 に答える