2017-05-04 5 views
1

こんにちは。私は答えを探しましたが、この特定の質問では見つかりませんでした。 Herearticleは、Visual C++コンパイラがさまざまな状況で冗長なコピーコンストラクタとデストラクタコールをどのように削除するかを示しています。私はClangとGCCについても同じことが当てはまると信じています。C++。オブジェクトを返すか、参照を渡して塗りつぶすか?

入力データWaveformと結果Analyzedの2つの構造体があります。そして、2つの関数は同じ作業を行いますが、異なる方法で結果を返します。 1stはローカルAnalyzedを作成し、それを返します(コピー).2番目は既に作成されたオブジェクトを参照してそれを埋め込み、それを返します。

struct Waveform; 
struct Analyzed; 

Analyzed analyze(Waveform const& wf); // Form 1 
Analyzed& analyze(Waveform const& wf, Analyzed& an); // Form 2 

スコープにすでにWaveform wfを想定した使用例、:フォーム1が短く、より便利である私として

auto an0 = analyze(wf); 
Analyzed const& an1 = analyze(wf); 

Analyzed an3; 
analyze(wf,an3); 

私が知る限り、Cでは、事前に割り当てられたメモリへの関数ポインタ(ユーザーはメモリの責任を負う)に渡し、sizeof(int)より大きいオブジェクトを返しませんが、ポインタまたはエラー番号を返しません。

質問です。analyze()フォームのほうが良いですか?どうして?
パフォーマンス上の問題、余分なコピー、落とし穴はありますか?
特別なケースがありますか?


私もフォーム1フォーム2を再利用する方法を想像することができます:

Analyzed analyze(Waveform const& wf){ 
    Analyzed an; 
    analyze(wf,an); 
    return an; 
} 

<スポイラー> 長い説明を。 2つの構造体があります:Waveformは信号を表し、Analyzed - 信号の特性です。

struct Waveform { 
    size_t len; 
    float *arr; 
    float sampleRate; 
    //... 
} 

struct Analyzed { 
    struct Entry { size_t idx; float value; }; 
    Entry max; 
    Entry min; 
    float peakToPeak; 
    float mean; 
    //... 
}; 

Analyzed analyze(Waveform const& wf); 
Analyzed& analyze(Waveform const& wf, Analyzed& an); 
+0

これはCタグとは関係ありません。 –

+0

@SouravGhosh Cタグを追加しました。「... Cは良い習慣であると考えています...」 – kyb

+0

これは問題ありませんが、ここにはタグはありません。\ –

答えて

1

このフォームは現在、多くの人に好まれる:

auto a = analyze(wf); 

それを書くのは簡単で、理解するのは簡単です。何も悪くなることはありません。 C++ 17のドラフト仕様には、中間の一時オブジェクトが関与しないという保証が含まれています。 C++ 14はそのオプションを作った。ほとんどのコンパイラがこのオプションを採用しました。

あなたとこれを比較する場合は、次の主要な違いの

Analyzed an; 
analyze(wf, an); 

2つです:

  • それはアウト」、関数の引数は「中」であるかどうかのコードを読んでからだけでは明らかではありません"、または" in-out "パラメータを使用します。あなたはドキュメントを参照する必要があります。
  • Analyzedにdefault-constructorがない場合、これはまったく機能しません。それは珍しいことではない。コンストラクタにオブジェクトを設定させることは、オブジェクト指向の優れた原則に従っています。後で "初期化"されるダミーシェルをコンストラクタに作成させるのではなく、

両方とも、コードが理解しにくくなり、コードミスが発生する可能性が高くなります。

関連する問題