关于以下shared_ptr
构造函数的问题:
template< class Y >
shared_ptr( const shared_ptr<Y>& r, T *ptr );
我是否正确,如果r
是使用用户提供的删除器创建的,那么别名就shared_ptr
知道了。因此,如果别名shared_ptr
是组中的最后一个并且(超出范围时)破坏了最初由 管理的资源r
,它将使用用户提供的删除器吗?
关于以下shared_ptr
构造函数的问题:
template< class Y >
shared_ptr( const shared_ptr<Y>& r, T *ptr );
我是否正确,如果r
是使用用户提供的删除器创建的,那么别名就shared_ptr
知道了。因此,如果别名shared_ptr
是组中的最后一个并且(超出范围时)破坏了最初由 管理的资源r
,它将使用用户提供的删除器吗?
例子:
#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 调用!
注意我不能用自由函数编译这个例子,自由函数my_deleter
有一些转换错误get_deleter
(试图void*
用 a 转换为函数指针类型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
模板 shared_ptr(Y* p, D d);
效果:构造一个拥有该对象
shared_ptr
和删除器的对象。p
d
Dtor:[util.smartptr.shared.dest]/1
~shared_ptr();
1效果:
- 如果
*this
为空shared_ptr
或与另一个实例共享所有权(use_count() > 1
),则没有副作用。- 否则,如果
*this
拥有一个对象p
和一个删除器d
,d(p)
则调用。- 否则,
*this
拥有一个指针p
,并被delete p
调用。
结合这些(让我们跳过赋值运算符):
shared_ptr
实例同时r
拥有对象和删除器。shared_ptr
实例与(即对象和删除器)共享所有权。r
use_count > 1
,则没有影响。r
指向的对象和删除器(如果有),并将使用此删除器(如果存在)或delete
指向的对象。是的,因为删除器存储在 shared_ptr 的计数器(“pn”成员boost::detail::shared_count
)中,并且别名实际上共享该计数器。