[解決済み] C++で「オブジェクトを返す」方法とは?
質問
似たような質問が多いのでタイトルは聞き覚えがあると思いますが、違う側面からの質問です(スタックに物があることとヒープに置くことの違いはわかります)。
Javaでは、常に"local"オブジェクトへの参照を返すことができます。
public Thing calculateThing() {
Thing thing = new Thing();
// do calculations and modify thing
return thing;
}
C++で同様のことを行うには、2つのオプションがあります。
(1) オブジェクトを返す必要があるときは、参照を使用することができます。
void calculateThing(Thing& thing) {
// do calculations and modify thing
}
そして、次のように使用します。
Thing thing;
calculateThing(thing);
(2) あるいは、動的に割り当てられたオブジェクトへのポインタを返すことができる。
Thing* calculateThing() {
Thing* thing(new Thing());
// do calculations and modify thing
return thing;
}
そして、次のように使用します。
Thing* thing = calculateThing();
delete thing;
最初の方法を使えば、手動でメモリを解放する必要はありませんが、私にはコードが読みづらくなってしまいます。2つ目の方法の問題点は、「メモリ解放のために
delete thing;
というのは、あまりいい感じではないですね。コピーした値を返すのは非効率的なのでやりたくない(と思う)ので、ここで質問です。
- 3番目の解決策(値をコピーする必要がない)はありますか?
- 最初の解決策にこだわっても問題はないのでしょうか?
- どのような場合に、どのような理由で、2番目の解決策を使うべきでしょうか?
どのように解決するのですか?
<ブロッククオートコピーした値を返すのは非効率なので避けたい
証明しなさい。
RVOとNRVO、そしてC++0xのmove-semanticsを調べてみてください。C++03では、ほとんどの場合、outパラメータはコードを醜くするための良い方法であり、C++0xではoutパラメータを使うことで実際に自分を傷つけてしまうことになります。
きれいなコードを書き、値で返すだけです。もしパフォーマンスが問題なら、それをプロファイルし(推測をやめ)、それを修正するために何ができるかを見つけてください。それはおそらく、関数から何かを返すことではないはずです。
とはいえ、どうしてもそういう書き方をしたいのであれば、アウトパラメータにしたほうがいいかもしれませんね。動的なメモリ割り当てを避けることができるので、より安全で一般的に高速になります。ただし、関数を呼び出す前にオブジェクトを構築する必要があり、すべてのオブジェクトに対して常に意味があるわけではありません。
もしダイナミック・アロケーションを使いたいのであれば、最低限できることはスマート・ポインターの中に入れておくことです。(これはいずれにせよ常に行われるべきことです) そうすれば、何かを削除する心配はなく、物事は例外的に安全です、等々。唯一の問題は、とにかく値で返すより遅いということです。
関連
-
[解決済み】Visual Studio 2015で「非標準の構文。'&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み] エラーが発生する。ISO C++は型を持たない宣言を禁じています。
-
[解決済み】C++ 式はポインタからオブジェクトへの型を持っている必要があります。
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] 変数を参照渡しする方法を教えてください。
-
[解決済み] 割り当て後にリストが予期せず変更されました。その理由と防止策を教えてください。
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] JavaScriptでオブジェクトのキー/プロパティの数を効率的にカウントする方法
-
[解決済み] JavaScriptで複数の値を返す?
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Visual Studio 2015で「非標準の構文。'&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み】C++でランダムな2倍数を生成する
-
[解決済み】C++ 式はポインタからオブジェクトへの型を持っている必要があります。
-
[解決済み】C++エラー:の初期化に一致するコンストラクタがありません。
-
[解決済み】cc1plus:エラー:g++で認識されないコマンドラインオプション"-std=c++11"
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)
-
[解決済み] to_string は std のメンバーではない、と g++ が言っている (mingw)
-
[解決済み】デバッグアサーションに失敗しました
-
[解決済み】エラー。引数リストに一致するコンストラクタのインスタンスがない