Wrapping a releaseable object into a smart pointer

前端 未结 3 1446
执笔经年
执笔经年 2021-01-25 19:41

As far as I understand the smart pointers, they are there to avoid memory leaks among other things. However there are often objects which also need to be released, but not by

相关标签:
3条回答
  • 2021-01-25 20:07

    You can construct both shared_ptr (signature #3 here) and unique_ptr (signature #2 here) with custom deleters.

    using T = ...;
    auto deleter = [](T* x) { delete x; };
    
    // different deleter - different unique_ptr type
    // deleter is stored inline
    auto x = std::unique_ptr<T, decltype(deleter)>(new T(...), deleter);
    
    // same shared_ptr<T> type regardless of the deleter type,
    // deleter is stored in the "shared state"
    auto y = std::shared_ptr<T>(new T(...), deleter);
    

    Note, make_shared() cannot be used to construct a shared_ptr with custom deleter.

    0 讨论(0)
  • 2021-01-25 20:11

    Both shared_ptr and unique_ptr provide that facility.


    For shared_ptr, the constructor is a template:

    An optional deleter d can be supplied that is later used to destroy the object when no shared_ptr objects own it. By default, a delete-expression for type Y is used as the deleter.

    In this case, the deleter can be any callable, copy-constructible value, which get type-erased to the callable.

    For unique_ptr, the type of the deleter is a type parameter of the pointer itself:

    template<
        class T,
        class Deleter = std::default_delete<T>
    > class unique_ptr;
    

    There's no erasure in this case, and the deleter provided to the c-tor or the reset actually matches the deleter type.

    0 讨论(0)
  • 2021-01-25 20:24

    If you are using unique_ptr or shared_ptr, you can provide your custom deleter. The deleter for a unique_ptr is passed as a template parameter, and

    Deleter must be FunctionObject or lvalue reference to a FunctionObject or lvalue reference to function, callable with an argument of type unique_ptr<T, Deleter>::pointer

    For the shated_ptr, the deleter should be provided as the constructor parameter.

    class Foo
    {
    
    };
    
    class Deleter
    {
    public:
        void operator()(Foo *)
        {
            std::cout << "deleter";
        }
    };
    
    int main() {
        std::unique_ptr<Foo, Deleter> ptr(new Foo());
        std::shared_ptr<Foo> ptr1(new Foo(),
                                 [](Foo*){std::cout << "deleter for shared_ptr";}
                                 );
    }
    

    You have to be careful not to cause memory leaks, though.

    0 讨论(0)
提交回复
热议问题