shared_ptr aliasing constructor

为君一笑 提交于 2019-11-29 18:36:03

问题


Question about following shared_ptr constructor:

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

Am I correct that if r was created using user-provided deleter, then aliasing shared_ptr knows that. So if aliasing shared_ptr is last in the group and (when going out of scope) destructs resources originally managed by r, it will use that user-provided deleter?


回答1:


Example:

#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;
}

Output:

1
2
1
get_deleter == 0? false
my_deleter called!

N.B. I can't compile this example with a free function my_deleter, there's some casting error for the free get_deleter function (trying to cast from void* to a function pointer type with a static_cast).


Aliasing ctor: [util.smartptr.shared.const]/13-14

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

13 Effects: Constructs a shared_ptr instance that stores p and shares ownership with r.

14 Postconditions: get() == p && use_count() == r.use_count()

Ctor with user-provided deleter: [util.smartptr.shared.const]/9

template shared_ptr(Y* p, D d);

Effects: Constructs a shared_ptr object that owns the object p and the deleter d.

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

~shared_ptr();

1 Effects:

  • If *this is empty or shares ownership with another shared_ptr instance (use_count() > 1), there are no side effects.
  • Otherwise, if *this owns an object p and a deleter d, d(p) is called.
  • Otherwise, *this owns a pointer p, and delete p is called.

Combining those (let's skip the assignment operators):

  • The shared_ptr instance r owns both the object and the deleter.
  • The aliasing ctor lets the new shared_ptr instance share ownership with r (i.e. for both, the object and the deleter).
  • When the dtor of this new instance is called (or an assignment operator),
    • If use_count > 1, no effects.
    • Else, this instance owns the object which r pointed to and the deleter (if any) and will either use this deleter (if it exists) or delete on the object pointed to.



回答2:


Yes, because a deleter is stored in the shared_ptr's counter (the 'pn' member boost::detail::shared_count) and aliasing actually shares the counter.



来源:https://stackoverflow.com/questions/19102034/shared-ptr-aliasing-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!