ええと... このタイプの質問には、正しい答えがないことが多いという慰めがあります. あなたが望む最善の方法は、長所と短所を詳しく説明する専門知識を示して、面接官を驚かせることです (別名、コード マスターベーション)。
スタイルの観点からすると、値による戻りを使用してオブジェクトを返すのはよくありません。検討:
X f();
X x;
x = f();
f は X を割り当てます。X を返す必要があるため、追加のコピーが戻り値としてスタックに配置されます。最後に、スタック上の x が代入演算子を介して x にコピーされます。全部で 3 つの X がメモリに表示されます。これは非効率的であると言う人もいるかもしれません。そのため、値がオブジェクトの場合は、値で返さないようにする必要があります。
しかし、より知識のあるインタビュー対象者は、次のように指摘したかもしれません。
- 一部のコンパイラは一時コピーを最適化します。この最適化では、X への代入がコピー コンストラクターまたは等値演算子のどちらを介して行われるかによって違いが生じると思います。「コピー エリソン」と言って、インタビュアーが眉をひそめるかどうかを確認します。コピー エリソンとは何ですか。. 関数が同じ翻訳単位にあり、したがって簡単にインライン化できるため、ここでコピー省略が機能する可能性があると思います。
- 文字列クラスのほとんどすべての実装は、コピー オン ライトを実装します。この場合、文字列のテキスト データの 1 つのコピーが保持され、残りのデータはスタックに保持され、文字列が処理されたときに基本的にオーバーヘッドは発生しません。コピーしました。
- 初期バージョンの Visual Studio を使用している場合、メモリ リークが発生します。
それで、どのような選択肢がありますか?
X const& f();
代替案として考えられます。ただし、結果の有効期間が呼び出し元には不明であるため、これには独自のスタイルの問題があります。次の呼び出しで前回の参照結果が無効になるのではないでしょうか? 知るか?
また
void f_get( X& result );
好まれるかもしれません(一部のインタビュアーによって)。これには次の利点があります。
- ローカル変数のコピーなし
- 不確定な寿命の参照/ポインターはありません
- X が文字列の場合、テキスト データのコピーは 1 つだけ保持されます (ただし、これはすべての場合に当てはまります)。
どちらの場合も、可読性が犠牲になります。一般的なケースでは、呼び出し元は、どの引数が関数パラメーターで、どの引数が結果を保持することを意図しているかに、より注意を払う必要があります。
OPでは、スタック上の文字列リテラルの寿命が何であるかも明らかではないかもしれません。関数が戻ったときにスタックから割り当て解除されますか? おそらくそうではありません-おそらく静的メモリ領域に保持されます(仕様を確認するのが最善です)。しかし、そうでない場合、結果はどうなりますか-文字列はおそらくヒープ上に char const* のコピーを作成するため、コンストラクターがリテラルと非リテラルパラメーターの区別を巧妙なテンプレートタイプで伝えることができる奇妙な文字列実装を持っていない限り、おそらく何もありません・特性魔法。
いずれにせよ、このようにいくつかの BS を吐き出すことは、的外れであれば、確実にポイントを獲得していただろう.
また、コンソールは ascii、UTF-8、または unicode を出力していますか? このプログラムはおそらくそのうちの 1 つで間違っており、英語を話さないロケールでも間違っています。
stdout が有効な値であることを確認しましたか、または Windows で -D_CONSOLE を使用せずにコンパイルしていますか、または stdout が利用できず、ログ ライブラリにリダイレクトする (またはクラッシュする) 必要がある組み込みデバイスまたはゲーム コンソール用ですか?
ええと...あなたの選択をしてください。
一時的なコピーは、おそらく彼らが探していたドロイドでした. 文字列の場合、テンポラリは重要ではないため (おそらくコピー省略も)、インタビュアーはエルダーベリーのにおいがし、母親はヤギでした。