9

shared_ptr次のコンストラクタに関する質問:

template< class Y >
shared_ptr( const shared_ptr<Y>& r, T *ptr );

rユーザー提供の削除ツールを使用して作成された場合、エイリアシングはそれを認識していることを修正しshared_ptrます。エイリアシングshared_ptrがグループの最後にあり、(範囲外になると) によって最初に管理されていたリソースrを破棄する場合、そのユーザー提供の削除機能を使用しますか?

4

2 に答える 2

5

例:

#include <iostream>
#include <iomanip>

struct some_type
{
    int i;
};

void my_deleter(some_type* p)
{
std::cout << "my_deleter called!" << std::endl;
    delete p;
}

#include <memory>
int main()
{
    std::shared_ptr<int> pm;

    {
        // Note: better use make_shared
        auto x = new some_type;
        // create a shared_ptr that owns x and a deleter
        std::shared_ptr<some_type> r(x, &my_deleter);
        std::cout << r.use_count() << std::endl;

        // share ownership of x and the deleter with pm
        pm = std::shared_ptr<int>(r, &r->i);
        std::cout << r.use_count() << std::endl;

        // r gets destroyed
    }
    std::cout << pm.use_count() << std::endl;
    std::cout << "get_deleter == 0? " << std::boolalpha
              << (nullptr == std::get_deleter<decltype(&my_deleter)>(pm))
              << std::endl;
}

出力:

1
2
1
get_deleter == 0? 間違い
my_deleter が呼び出されました!

注意: この例を free functionmy_deleterでコンパイルすることはできません。free 関数のキャスト エラーがあります (を使用して関数ポインター型get_deleterにキャストしようとしています)。void*static_cast


エイリアシング ctor: [util.smartptr.shared.const]/13-14

template<class Y> shared_ptr(const shared_ptr<Y>& r, T *p) noexcept;

13効果:と所有権をshared_ptr保管pおよび共有するインスタンスを構築しますr

14事後条件: get() == p && use_count() == r.use_count()

ユーザー提供のデリータを含む Ctor: [util.smartptr.shared.const]/9

template shared_ptr(Y* p, D d);

効果: objectと deleterを所有shared_ptrするオブジェクトを構築します。pd

Dtor: [util.smartptr.shared.dest]/1

~shared_ptr();

1効果:

  • *thisshared_ptrであるか、別のインスタンス ( )と所有権を共有している場合use_count() > 1、副作用はありません。
  • それ以外の場合、がオブジェクトを*this 所有しpdeleterが呼び出される場合。dd(p)
  • それ以外の場合は、ポインターを*this 所有し、呼び出されます。pdelete p

それらを組み合わせます(代入演算子をスキップしましょう):

  • shared_ptrインスタンスは、オブジェクトとデリータの両方をr 所有しています。
  • エイリアシング ctor は、新しいshared_ptrインスタンスが所有権を共有rできるようにします(つまり、オブジェクトと削除の両方に対して)。
  • この新しいインスタンスの dtor (または代入演算子) が呼び出されると、
    • の場合use_count > 1、影響はありません。
    • それ以外の場合、このインスタンスは、指し示したオブジェクトとデリータ(存在する場合) を所有し、このデリータ (存在する場合) または指されたオブジェクトで使用します。rdelete
于 2013-09-30T19:36:03.783 に答える