问题
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_ptrinstance that storespand shares ownership withr.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_ptrobject that owns the objectpand the deleterd.
Dtor: [util.smartptr.shared.dest]/1
~shared_ptr();
1 Effects:
- If
*thisis empty or shares ownership with anothershared_ptrinstance (use_count() > 1), there are no side effects.- Otherwise, if
*thisowns an objectpand a deleterd,d(p)is called.- Otherwise,
*thisowns a pointerp, anddelete pis called.
Combining those (let's skip the assignment operators):
- The
shared_ptrinstancerowns both the object and the deleter. - The aliasing ctor lets the new
shared_ptrinstance share ownership withr(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
rpointed to and the deleter (if any) and will either use this deleter (if it exists) ordeleteon the object pointed to.
- If
回答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