59

重複の可能性:
const 参照は一時オブジェクトの寿命を延ばしますか?
一時的な寿命を延ばす

C++ では、一時オブジェクトを const 参照にのみ割り当てることができます。参照する一時オブジェクトの割り当てを許可しません。

例えば:

String& a = String("test");         // Error
const String& a = String("test");   // Ok

この結果をグーグルで検索しても、次の回答しか表示されません

  1. 一時オブジェクトを変更すると、識別できない問題が発生する可能性があります
  2. 一時オブジェクトの変更は危険です
  3. ある時点で、それが一時変数であることを忘れるでしょう

一時オブジェクトはステートメントの後に消えると言われています。したがって、変更しないでください。

C++ が一時オブジェクトの変更をブロックすることに非常に熱心である場合、一時オブジェクトの読み取りをブロックする必要がありますか? 一時オブジェクトが消失した場合、そこから内容を読み取っても意味がありませんよね? 権利が発生する可能性のあるケースには、読み取りも含まれる可能性があります。

では、なぜ書き込みのみをブロックし、読み取りを許可しているのでしょうか?

しっかりとしたC++コードの説明をお願いします。

いくつかの代替案を指摘して質問を逸脱しないでください。const int & が許可され、 int & が一時オブジェクトに許可されない理由をコードで明確に答えてください。

&&がそこにあると言う..私の質問は違う..別の言い方をすると、変更しても反映されない.. const int & tooであっても、変更しても反映されません。例: ダブル a; 定数 int & i = a; ++; 影響しません。

4

4 に答える 4

38

一時変数への参照を許可しない元のケースは、関数パラメーターでした。これが許可されたとします。

void inc(double& x)
{ x += 0.1; }

int i = 0;
inc(i);

なぜi変更されないのですか?

于 2012-12-11T19:24:47.997 に答える
18

C++ が一時オブジェクトの変更をブロックすることに非常に熱心である場合、一時オブジェクトの読み取りをブロックする必要がありますか? 一時オブジェクトが消失した場合、そこから内容を読み取っても意味がありませんよね?

いいえ、オブジェクトを読み取ることは完全に賢明です。将来消えてしまうからといって、データを読むことが無意味というわけではありません。

open_file(std::string("foo.txt"));

std::string("foo.txt")の呼び出し後に存在を停止する一時的なものですが、open_file()存在している間に含まれるデータは非常に重要です。

一時変数を const 以外の参照にバインドできないようにする理由は、一時変数への書き込みに関する根本的な問題ではありません。実際、多くの場所で、C++ は一時的な変更を完全に許可しています。

std::string("foo") = "bar";

設計者は、同様の値を有効にせずに十分な数の問題を引き起こすと感じただけです (おそらく「出力パラメーター」の一般的なイディオムによる)。参照。

右辺値参照を使用すると、以前は禁止されていたことを正確に実行できるようになりました。

void foo(int &&output) {
    output = 1;
}

foo(2);

これはうまく機能しますが、あまり役に立ちません。

于 2012-12-11T19:39:25.500 に答える
6

コピーするのに非常にコストがかかる一時オブジェクトがある場合は、const&後で使用するために別の変数にコピーするよりも、そのオブジェクト (関数の戻り値など) を使用することをお勧めします。テンポラリへの一定の参照を取得すると、そのテンポラリの寿命が参照が存続する限り延長され、読み取り可能な状態にアクセスできるようになります。

変数を変更したい場合はすぐに、非 const 参照としてのみエイリアス化された一時インスタンスではなく、実際のインスタンスを使用する可能性があるため、書き込みは許可されていません。

于 2012-12-11T19:23:21.810 に答える
1

これには論理的な理由があります。この行で実際に何が必要か考えてみてください。

String& a = String("test");         // Error

参考にしたい。参照は、それが参照するオブジェクトに関連しています。オブジェクトのアドレスのように (参照はアドレスではありませんが、この方法で説明をより明確にします)。実際に のアドレスのようなものを取得しようとしますString("test")。しかし、そのオブジェクトは次の行ですぐに消えてしまうので、オブジェクトが指しているオブジェクトが存在しない場合、そのアドレスの意味は何でしょう? a今、意味のない何かを指しています...

2 番目の質問については、一時オブジェクトをすべて一緒に許可するポイントは何ですか。まあ、それは何も悪いことではありません。たとえば、Stringオブジェクトを関数に渡したい場合を考えてみましょう。関数は、たとえば、その文字列に対応する変更された文字列を返します。関数 DoubleString を呼び出しましょう。

String s("hello ");
String s2 = DoubleString(s);

より短く、より便利なフォームを使用できます

String s2 = DoubleString(String("hello "));

見てください、一時オブジェクトString("hello ")はコードの行全体を生き残りますDoubleString。ライン全体が終了したときにのみ破棄されます。

于 2012-12-11T19:27:12.700 に答える