関数からローカル変数への const 参照を返す
-
13-09-2019 - |
質問
関数からローカル変数への参照を返すことについていくつか質問があります。
class A {
public:
A(int xx)
: x(xx)
{
printf("A::A()\n");
}
};
const A& getA1()
{
A a(5);
return a;
}
A& getA2()
{
A a(5);
return a;
}
A getA3()
{
A a(5);
return a;
}
int main()
{
const A& newA1 = getA1(); //1
A& newA2 = getA2(); //2
A& newA3 = getA3(); //3
}
私の質問は=>
の実装です
getA1()
正しい?ローカル変数または一時的なアドレスを返しているので、間違っていると感じます。次のステートメントはどれですか
main
(1,2,3) は未定義の動作を引き起こしますか?で
const A& newA1 = getA1();
標準は、const 参照によって一時的にバインドされた参照がスコープ外になるまで破棄されないことを保証していますか?
解決
1。
getA1()
実装は正しいですか?私はそれがローカル変数または一時的のアドレスを返しているとして、それが間違っている気がします。
あなたのプログラムに正しいgetAx()
の唯一のバージョンがgetA3()
です。他の人の両方が、あなたが後でそれらを使用する方法に関係なく、未定義の動作をしていない。
2。未定義の動作にメイン(1,2,3)内の文のどちらをリードする?
それらの一つのセンスなしで。 1及び2のために未定義の動作は、機能の体の結果です。あなたは非constの参照に一時的に結合することができないとして最後の行について、newA3
はコンパイルエラーにする必要があります。
3。
const A& newA1 = getA1();
では、一時はconst
によって結合したことを、標準的な保証を行います 参照がスコープから外れるまで、参照が破壊されることはないのだろうか?
はありません。以下はその一例である:
A const & newConstA3 = getA3 ();
ここで、getA3()
は現在のオブジェクトnewConstA3
にバインドされ、一時、その一時的なの寿命を返します。 newConstA3
がスコープの外に出るまで、言い換えれば、一時的に存在します。
他のヒント
Q1:はい、これは問題であり、Q2への答えを参照してください。
。Q2:彼らはgetA1とgetA2のスタック上のローカル変数を参照するように1及び2は不定れます。これらの変数はスコープの外に出ると、スタックは常に変化していると上書きされる可能性がもはや利用して悪化していません。戻り値のコピーが作成され、呼び出し元に返されるので、getA3は動作します。
Q3:いいえ、そのような保証はQ2への答えを見に存在しません。
。私は、主な問題は、あなたがすべてで一時帰国をしていないということだと思う、あなたべき
return A(5);
ではなく
A a(5);
return a;
それ以外の場合は、あなたが戻ってきているローカル変数のアドレス、一時的ではありません。そして、const参照に一時的にのみ一時のために働くます。
私は、ここで説明するのだと思います。 のconstへの一時的な参照する
は、
この警告が表示されます******コンパイラの警告(レベル1)C4172 帰国ローカル変数のアドレスまたは一時的な 機能は、ローカル変数や、一時的なオブジェクトのアドレスを返します。ローカル変数や、一時的なオブジェクトは関数が戻るときに破壊されるので、返されたアドレスが有効ではありません。******
この問題のためにテストしている間、私は興味深い(与えられたコードはVC6で動作している)を見つけます:
class MyClass
{
public:
MyClass()
{
objID=++cntr;
}
MyClass& myFunc()
{
MyClass obj;
return obj;
}
int objID;
static int cntr;
};
int MyClass::cntr;
main()
{
MyClass tseadf;
cout<<(tseadf.myFunc()).objID<<endl;
}