前言
C++11智能指针做出了诸多改进,特别是shared_ptr支持共享分配的内存区域,那么对于不同的share_ptr,它们相互赋值后,删除器如何调用,本文将探讨。
一、自定义share_ptr删除器
有多种方法自定义share_ptr的删除器,我们选择其中两种,删除器函数和删除器类。由于C++11的shared_ptr不支持数组,这里需要自定义删除器。
template <typename T>
void deletefun(T const *p)
{
cout << "templ func delete[] p" << endl;
delete[] p;
}
template <typename T>
class deleteclass
{
public:
void operator()(T const *p)
{
cout << "templ class delete[] p" << endl;
delete[] p;
}
};
调用方法分别为
shared_ptr<int> sp(new int[10], deleteclass<int>());
shared_ptr<int> sp(new int[30], deletefun<int>);
二、观察多个share_ptr调用删除器规则
1.代码
代码如下(示例):
void sharedptarr(shared_ptr<int> &sptPara)
{
shared_ptr<int> sp(new int[10], deleteclass<int>());
cout << __FUNCTION__ << " cont: " << sp.use_count() << endl;
sptPara = sp;
cout << __FUNCTION__ << " cont: " << sp.use_count() << endl;
}
int main()
{
shared_ptr<int> spint4(new int[30], deletefun<int>);
cout << __FUNCTION__ << " cont: " << spint4.use_count() << endl;
sharedptarr(spint4);
cout << __FUNCTION__ << " cont: " << spint4.use_count() << endl;
return 0;
}
2.输出结果
main cont: 1
sharedptarr cont: 1
templ func delete[] p
sharedptarr cont: 2
main cont: 1
templ class delete[] p
从此就可以看出, 当sptPara = sp,会先调用sptPara的删除器(因为此时只有一个share_ptr指向new int[30]那个区域),然后和sp指向同一个区域(new int[10]),同时引用次数+1,然后,当函数sharedptarr调用结束,sp的生命周期结束,引用次数-1,之后main函数执行完,执行deleteclass<int>()这个删除器。
总结
当一个share_ptr指向另一个share_ptr时,会释放本share_ptr的引用计数,当计数为0,则调用删除器,然后指向另一个share_ptr并计数+1。