C++ Primer中智能指针的一个小疑惑,是书中的bug?

C++中的管理指针成员方法,有一个是智能指针。

《C++ Primer》原书495,译本424这个位置

意思很简单,利用一个U_Ptr类充当HasPtr的私有计数类,防止多个HasPtr对象调用析构delete同一个基础对象(int)


class U_Ptr{
	friend class HasPtr;
	int *ip;
	size_t use;
	U_Ptr(int *p): ip(p), use(1) {}
	~U_Ptr(){delete ip;}
 };
class HasPtr{
public:
	//copy of the values we're given
	HasPtr(int *p, int i): ptr(new U_Ptr(p)), val(i){std::cout << "test: *ptr->ip is " << *ptr->ip << std::endl;}//constructor
	HasPtr(const HasPtr &orig): ptr(orig.ptr), val(orig.val){ ++ptr->use;}//copy members and increment the use count
	~HasPtr(){
		if(--ptr->use == 0)
			delete ptr;
	}
	HasPtr&
	operator=(const HasPtr &rhs){
		++rhs.ptr->use;
		if(--ptr->use == 0)
			delete ptr;
		ptr = rhs.ptr;
		val = rhs.val;
		return *this;
	}
	//其他操作
	int *get_ptr() const{	return ptr->ip;}
	int get_int() const{	return val;}
	void set_ptr(int *p){	ptr->ip = p;}
	void set_int(int i){	val = i;}
	int get_ptr_val() const{	return *ptr->ip;}
	void set_ptr_val(int val) const{	*ptr->ip = val;}
	
private:
	U_Ptr *ptr;
	int val;
};



示例代码:

int main(){
	
	int *p = new int( 42);//问题也不是在这
	{	
		HasPtr ptr1(p, 20);
		HasPtr ptr2(ptr1);
		HasPtr ptr3(ptr2);

		HasPtr ptr4(p, 77);//ptr4需要另一个U_Ptr对象,因此delete ptr两次
                //两个U_Ptr对象里分别delete一次,指向相同基础对象却没冲突?想delete多少次都成?

		ptr4 = ptr2;//赋值操作,会删除ptr4指向的U_Ptr,此U_Ptr的析构会delete ip,也就是delete p,后边还能正常运行~!
		/*加此句必错
		   delete p;	
                */
	}//超出scope,第二次析构
}



就是这么个意思ptr1、ptr2和ptr3都通过一个U_Ptr对象指向基础对象*p

ptr4是通过另一个U_Ptr指向基础对象*p的,那么两次的delete ip;怎么能通过,ip直接等价p啊,先delete p;再析构是肯定出错的。


摘抄(p425)

建议:管理指针成员

“但它们使用复制控制技术以避免常规指针的一些缺陷。”----根据上下文,只是说相应计数加减和析构函数使用条件的控制,这句话不应该等同于只能使用复制,所以我的ptr4是合乎规范的。

“同一基础值的每个副本都有一个使用计数”----但是这个语句不像给基础值副本了啊,如果U_Ptr存储了基础对象的副本,那么函数块最后那句delete p;是伤不到函数块结束的析构函数的,何况,根据后边的值型类,想存储副本还是需要new int(*p) 来完成,而不是单独的一个把让ip同p指向相同位置吧。




解释只有两个,这个智能指针是错的,太矛盾。

第二个解释是,作者们不可能没这个逻辑,太明显的错误,这个智能指针是在极大的限制前提 下使用的,觉得应该有相应使用前题,但是前前后后翻翻,也没找到,奇了怪了~!


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值