5

重複の可能性:
C++で「オブジェクトを返す」方法

こんにちは、みんな!

関数からオブジェクトを返す必要がある場合(そしてそれはゲッターではなく、この関数は何らかの理由でコンストラクターとして実装できません。たとえば、同じ署名と異なるセマンティクスを持つコンストラクターがあります)、どのように実装するのが良いですか?これ?

たとえば、次のオプションを提案できます。

1)オブジェクト自体を返します。

MyClass GetMyClass() {
    MyClass a;
    ...
    return a;
}

ほとんどの場合、RVO、http://en.wikipedia.org/wiki/Return_value_optimizationが実行され、コピーコンストラクターは呼び出されず、オーバーヘッドはありません。このアプローチの欠点は、RVOにもかかわらず、MyClassのコピーコンストラクターを指定する必要があることですが、GoogleC++スタイルガイドで説明されているように...

C ++でのオブジェクトの暗黙的なコピーは、バグやパフォーマンスの問題の豊富な原因です。

2)オブジェクトへのポインタを返します。

MyClass* GetMyClass() {
    MyClass* a= new MyClass();
    ...
    return a;
}

このような場合、ヒープにメモリを割り当てるため、オーバーヘッドが発生します。これにより、mallocシステムコールが原因でプログラムの速度が低下します。また、この関数の外部でメモリを解放する必要があります。つまり、割り当てと解放は異なる論理ユニットで実行されます。ここで述べたように、関数内のmallocメモリを外部に解放するのはなぜ悪い考えですか?多くの場合、それは悪い考えです。

3)参照またはポインタで値を渡します。

void GetMyClass(MyClass& a) {
    ...
}

この場合、コードは醜くなり、読みにくくなります

ベストプラクティスは何ですか?プロジェクトでどちらを使用し、大きなプロジェクトで作業するときに最も重要な基準はどれですか。

4

2 に答える 2

4

2つは非常に簡単です。はい、mallocは遅くなる可能性がありますが、あなたの場合は重要ですか?どこかからそのオブジェクトのためのスペースが必要です。また、あなたが指摘した質問の答えにも注意してください。問題があるのは論理ユニット全体だけです。問題があるかどうかを確認してから、事前に最適化するのではなく、修正してみてください。

無料のストアとマネージャーのリソース自体を使用する独自のバージョンのnewを作成できる可能性があります。ただし、測定して新しい問題が見つかった場合を除いて、エラーが発生しやすくなります。

ポインタを解放する際の問題を改善するのに役立つ1つの方法は、std::shared_ptrを使用することです。そうすれば、常にスマートポインターを介してオブジェクトを使用する限り、オブジェクトを解放することを心配する必要はありません。

于 2012-11-02T20:11:25.853 に答える
2

移動可能なオブジェクトを返すという明らかな機会を省略しました。戻り値によって多くの場合オーバーヘッドが削減される可能性がありますが、誤ってコピーされるリスクはありません。C ++ 2011が利用できない場合は、型をコピー可能にして値で返します。

移動もコピーもオプションではない場合、私はポインタを返します。もちろん、私は裸のポインターを返しませんがstd::unique_ptr<T>(またはstd::auto_ptr<T>利用できない場合):スマートポインターを使用すると、メモリリークのリスクを回避できますが、たとえば、ではなく軽量ポインターを選択してもstd::shared_ptr<T>、最終的なポリシー決定は行われません。オブジェクトがどのように維持されるかについて。オブジェクトを面白い方法で解放する必要がある場合は、削除機能が付属している可能性があります。

于 2012-11-02T20:13:03.733 に答える