C++Primer中 智能指针一例分析

近期复习《C++Primer》,用的第四版。在13章复制控制中,书上给出了一个自定义智能指针的例子。代码见下,纯抄书。

关于这个例子,自己之前有个疑问,一直没能解答,就是为什么我们已经用了U_Ptr class 封装了实际使用的 int*, 在U_Ptr里面维护了一个int* 的引用计数,为啥还要再用HasPtr class 再封装一次U_Ptr? 显然这里暴露给外部使用的是HasPtr, 它才是所谓的智能指针。

class U_Ptr{
	friend class HasPtr; //here only accessiable for HasPtr
	int *ip;	
	size_t use;
	U_Ptr(int *p): ip(p), use(1){}
	~U_Ptr(){delete ip;}	
};
class HasPtr{
public:
	//HasPtr owns the pointer, p must have been allocated dynamically
	HasPtr(int *p, int i): ptr(new U_Ptr(p)), val(i){}
	//copy constructor
	HasPtr(const HasPtr &orig):
		ptr(orig.ptr), val(orig.val){++ptr->use;}
	//copy assign operator
	HasPtr& operator=(const HasPtr&);	
	~HasPtr(){
		if(--ptr->use == 0)
			delete ptr;		
	}
	
	//other operation via *ptr
	int *get_ptr() const{return ptr->ip;}
        ...
private:
	U_Ptr *ptr;
	int val;	
};
这回复习重新把这段代码敲了一遍,在敲 ~HasPtr() 析构函数的时候,忽然明白了。

如果没有HasPtr()这一层,~U_Ptr()中就必须加上引用计数减1这段逻辑,并且只能在引用计数减到0时,删除原指针所指向的内存部分(这里是简单的ip)。可是,int* ip是在U_Ptr中被创建的,如果U_Ptr被析构了,那么ip肯定会被析构。

问题来了,我们希望的是,智能指针被析构时,所封装的原指针并不立刻被析构,这也正是我们费尽心思使用引用计数的原因。原指针本身的析构我们肯定是不能染指的,不管是原生类型如int*,还是 ClassA*, 对于外层的智能指针来说,必须是不可见的。

怎么办? 最简单的方式,就是再加一层封装,如这里的HasPtr。 这样我们可以控制U_Ptr的析构时间,从而将原指针的析构和内存释放推迟到没有任何一个引用存在的时候。

曾经读一本介绍内核的书时,在头一章看到一句话:软件上的任何问题,都可以通过多加一个中间层来解决。其实这里智能指针中的设计,同样沿用这个思想。

ps,实际应用中,智能指针的实现方法和思路应该有很多,比如很多框架库。C++Primer只是借这个最简单的例子,管中窥豹,这篇短博,也是如此。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值