[解決済み] C++ ローカル変数への参照を返す
2022-02-15 11:17:11
質問
以下のコード(func1())は、iを返さなければならないのであれば、正しいのでしょうか?ローカル変数への参照を返すと問題があるとどこかで読んだ覚えがあります。func2()とはどう違うのでしょうか?
int& func1()
{
int i;
i = 1;
return i;
}
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
解決方法は?
このコードスニペットです。
int& func1()
{
int i;
i = 1;
return i;
}
なぜなら、関数呼び出しのスコープに限定されたライフタイムを持つオブジェクトへのエイリアス (参照) を返しているからです。つまり、一度
func1()
が返ります。
int i
が死ぬと、関数から返された参照は存在しないオブジェクトを参照することになり、価値がなくなります。
int main()
{
int& p = func1();
/* p is garbage */
}
2番目のバージョンは、変数が関数呼び出しのライフタイムに縛られないフリーストアに割り当てられるので、動作します。しかし、あなたは
delete
を使用すると、割り当てられた
int
.
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
int main()
{
int* p = func2();
/* pointee still exists */
delete p; // get rid of it
}
通常、ポインタをいくつかの
RAII
クラスやファクトリー関数を使うことで
delete
を自分で作る。
どちらの場合でも、値そのものを返せばいいのです(あなたの提供した例は、おそらく作為的なものだと思いますが)。
int func3()
{
return 1;
}
int main()
{
int v = func3();
// do whatever you want with the returned value
}
大きなオブジェクトを同じ方法で返すのは全く問題ないことに注意してください。
func3()
はプリミティブな値を返すので、現在ではほとんどのコンパイラが何らかの形で
戻り値の最適化
:
class big_object
{
public:
big_object(/* constructor arguments */);
~big_object();
big_object(const big_object& rhs);
big_object& operator=(const big_object& rhs);
/* public methods */
private:
/* data members */
};
big_object func4()
{
return big_object(/* constructor arguments */);
}
int main()
{
// no copy is actually made, if your compiler supports RVO
big_object o = func4();
}
興味深いことに、テンポラリにバインドすると コンスト 参照は 完全に合法な C++ .
int main()
{
// This works! The returned temporary will last as long as the reference exists
const big_object& o = func4();
// This does *not* work! It's not legal C++ because reference is not const.
// big_object& o = func4();
}
関連
-
[解決済み] string does not name a type Errorが発生するのはなぜですか?
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] std::stringをintに変換するにはどうしたらいいですか?
-
[解決済み] C++の参照変数を返す習慣は悪なのか?
-
[解決済み】C/C++の"-->"演算子とは何ですか?
-
[解決済み】高放射能環境下で使用するアプリケーションのコンパイルについて
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
-
[解決済み】C++ シングルトンデザインパターン
-
[解決済み】vtableへの未定義の参照
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】識別子 "string "は未定義?
-
[解決済み] [Solved] Error C1083: Cannot open include file: 'stdafx.h'
-
[解決済み】C++エラーです。"配列は中括弧で囲まれたイニシャライザーで初期化する必要がある"
-
[解決済み] error: 'if' の前に unqualified-id を期待した。
-
[解決済み】IntelliSense:オブジェクトに、メンバー関数と互換性のない型修飾子がある
-
[解決済み】「corrupted size vs. prev_size」glibc エラーを理解する。
-
[解決済み】エラー:strcpyがこのスコープで宣言されていない
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み] 数値定数の前にunqualified-idを付けて、数値を定義することを期待する。
-
[解決済み】Visual Studioのデバッガーエラー。プログラムを開始できません 指定されたファイルが見つかりません