8

私は仕事で私たちのプロジェクトの 1 つを構築していたところ、新しい機能が追加されたことがわかります。

const std::string& ClassName::MethodName() const
{
   return "";
}

コンパイラは警告を出します:

警告 C4172: ローカル変数または一時のアドレスを返す

コンパイラは正しいと思います。この機能は安全ですか?

const char*関数は、文字列リテラルが静的な保存期間を持っている限り、OK を返さないことに注意してください。への参照を返しますconst std::string

4

4 に答える 4

8

はい、安全ではありません。
ローカル変数またはテンポラリのアドレスを返し、それを逆参照すると、未定義の動作が発生します。

あなたがコメントしたように:
はい、定数参照にバインドされた一時的な寿命は、定数の寿命まで増加します。ただし、呼び出し元が const 参照で戻り値を受け入れる必要があるため、それ自体では関数は安全ではありません。

C++ 標準から:
C++03 12.2 一時オブジェクト:

2 番目のコンテキストは、参照がテンポラリにバインドされる場合です。参照がバインドされている一時、または一時がバインドされているサブオブジェクトへの完全なオブジェクトである一時は、以下に指定されている場合を除き、参照の存続期間中持続します...

コンストラクターの ctor-initializer (12.6.2) の参照メンバーへの一時的なバインドは、コンストラクターが終了するまで持続します。関数呼び出し (5.2.2) の参照パラメーターへの一時的なバインドは、呼び出しを含む完全な式が完了するまで持続します。関数 return ステートメント (6.6.3) の戻り値への一時的なバインドは、関数が終了するまで持続します。

于 2011-08-12T11:20:27.743 に答える
4

これは私にとって物事を明確にした例です:

#include <iostream>
using std::cout;
struct A{
   A()   {
      cout << "Ctor\n";
   }
   ~A()   {
      cout << "Dtor\n";
   }
};

const A& f(){
   return A();
}

int main(){
   const A& ref = f();
   cout << "1\n";
   {
      const A& ref1 = A();
      cout << "2\n";
   }
   cout << "3\n";
}

出力

Ctor
Dtor
1
Ctor
2
Dtor
3
于 2011-08-12T11:39:49.830 に答える
3
于 2012-08-21T20:42:04.767 に答える
3

あなたがしたことを実際に行うと、コンパイラで内部的にこれが行われます。

const std::string* ClassName::MethodName() const
{
   std::string temp = "";
   return &temp;
}

また、ローカル変数への参照またはポインターを返すのは良くありません。

于 2011-08-12T11:23:44.640 に答える