3

(または他のスマート ポインター)を使用するとstd::shared_ptr、ctor を介してカスタム アロケーター/デリータが割り当てられることに気付きました。これはたまたまテンプレートです。私の質問は次のとおりです。アロケータ/デリータはどのように保存および使用されますか?

これらのファンクターは、関数ポインター、void*または何として格納されますか? 間接呼び出しですか、それとも直接呼び出しですか。

私が尋ねようとしていることをより明確に理解するために、次のコードを検討してください。

struct SomethingAwesomeDeleter
{
public:
    void operator()(SomethingAwesome* ptr) const
    {
        // do something awesome
        delete ptr;
    }
};
typedef std::shared_ptr<SomethingAwesome> SomethingAwesomePtr;

SomethingAwesomePtr ptr{new SomethingAwesome, SomethingAwesomeDeleter{}};

SomethingAwesomeDeleter{}保管・使用方法は?

注:std::shared_ptrがテンプレート クラスである ことは認識std::shared_ptrしていますが、クラス テンプレート引数にデリータ/アロケータのテンプレート引数がありません。つまり、 のようなテンプレート クラスはありませんstd::shared_ptr<T, Allocator, Deleter>

4

1 に答える 1

3

には任意の関数オブジェクトを格納できますstd::function。これにより、関数ポインターを直接格納するか (単純な関数の場合)、オブジェクト内にラップすることができます。shared_ptrこれは、関数型をテンプレート型の一部にせずにデリータを実装する 1 つの可能な方法です。

例(テストされていません。アイデアを提供するためだけに)

// This is the struct which actually holds the shared pointer
// A shared_ptr would reference count this
template <typename T>
class shared_ptr_shared
{
    std::function<void (T*)> del_;
    T* p_;
    // other members

    template <typename Deleter>
    shared_ptr_shared (T* obj, Deleter deleter)
    : p_ (p)
    , del_ (deleter)
    {
    }

    ~shared_ptr_shared ()
    {
        if (del_) {
            del_ (p_);
        } else {
            delete p_;
        }
    }
};

std::function の詳細については、こちらをご覧ください: boost::function と boost::bind の仕組み

于 2013-01-01T10:27:37.743 に答える