通常のベース->派生階層:
class Fruit { ... };
class Pear : Fruit { ... };
class Tomato : Fruit { ... };
std::vector<Fruit*> m_fruits;
Push_backの代わりにemplace_backを使用することは理にかなっていますか(たとえば、パフォーマンスが優れています)。
std::vector::emplace_back( new Pear() );
std::vector::emplace_back( new Tomato() );
ポインターはスカラー型であるため、リテラル型であるため、(左辺値または右辺値からの)コピー、移動、配置の構築はすべて同等であり、通常は同じコードにコンパイルされます(スカラーコピー)。 _Push_back
_は、スカラーコピーを実行していることが明確ですが、_emplace_back
_は、非コピーコンストラクターまたは移動コンストラクター(例:変換コンストラクターまたは複数引数コンストラクター)を呼び出すエンプレース構築用に予約する必要があります。
ベクターが生のポインターの代わりに_std::unique_ptr<Fruit>
_を保持する必要がある場合(メモリリークを防ぐため)、変換コンストラクター_emplace_back
_を呼び出すため、より正確になります。ただし、ベクトルの拡張に失敗した場合でもリークする可能性があるため、その場合はPush_back(make_unique<Pear>())
などを使用する必要があります。
生のポインタを使用せず、std::unique_ptr
を次のように使用します。
std::vector<std::unique_ptr<Fruit>> m_fruits;
また、構造体std::unique_ptr
はコピーできないため、emplace_back
を使用する必要があります(Push_back
とstd::move
は併用できます)。
m_fruits.emplace_back(new Pear()); m_fruits.emplace_back(new Tomato());
編集:
std::vector<std::unique_ptr<T>>::emplace_back
が必要でメモリの再割り当てに失敗した場合、std::vector
およびnew
を使用するとリークする可能性があるため、私の推奨するアプローチ(C++ 14がstd::make_unique
を導入するまで)はこのようにPush_back
を使用するには:
m_fruits.Push_back(std::unique_ptr<Fruit>(new Pear));
m_fruits.Push_back(std::unique_ptr<Fruit>(new Tomato));
またはstd::make_unique
を使用:
m_fruits.Push_back(std::make_unique<Pear>());
m_fruits.Push_back(std::make_unique<Tomato>());