7

std::shared_ptrを使用せずに を作成した後、カスタムのデリータを使用することは可能newですか?

new私の問題は、オブジェクトの作成がファクトリ クラスによって処理され、そのコンストラクタとデストラクタが保護されているため、コンパイル エラーが発生し、その欠点のために使用したくないことです。

詳しく説明すると、次のような共有ポインターを作成することを好みます。これにより、カスタムのデリータを設定できなくなります (と思います)。

auto sp1 = make_shared<Song>(L"The Beatles", L"Im Happy Just to Dance With You");

または、次のように作成することもできます。これにより、met は引数を介してデリータを設定できます。

auto sp2(new Song, MyDeleterFunc);

しかし、2番目のものは を使用しますnew。これは、私の知る限り、一番上の種類の割り当てほど効率的ではありません。

たぶん、これはより明確です:make_shared<>カスタムのデリータと同様の利点を得ることは可能ですか? それは、アロケータを書かなければならないということでしょうか?

4

2 に答える 2

8

いいえ、カスタムのデリータを取るstd::make_sharedの形式はありません。

shared_ptrカスタムのデリータで aを返す必要がある場合は、パフォーマンスに影響を与える必要があります。

考えてみてください。使用するmake_sharedと、参照カウントとオブジェクトを一緒に格納できるより大きなメモリ領域が割り当てられ、配置 new が呼び出されます。shared_ptrから返されたmake_sharedには、オブジェクトのデストラクタを明示的に呼び出してから、より大きなメモリ ブロックを解放するカスタム デリータが既にあります。

于 2013-10-25T21:47:51.660 に答える
4

オブジェクトと. _ new_ _ _std::make_sharedstd::make_sharedshared_count

独自のカスタム デリータを使用して割り当てを最適化することはできないことを受け入れる必要がありますが、安全に使用std::make_sharedするために、-like ラッパーを使用してカプセル化する必要がnewあります。これは、オブジェクトのコンストラクターが例外をスローし、誰かが使用する場合のメモリ リークを回避するのに役立ちます。

template<typename T>
void f(const T&, const T&);

f( std::shared_ptr<X>(new X), std::shared_ptr<X>(new X) ); // possible leak

それ以外の

std::shared_ptr<X> make_X() { return std::shared_ptr<X>(new X); }
f( make_X(), make_X() ); // no leak
于 2013-10-25T21:45:56.650 に答える