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指向相同位置吧。
解释只有两个,这个智能指针是错的,太矛盾。
第二个解释是,作者们不可能没这个逻辑,太明显的错误,这个智能指针是在极大的限制前提 下使用的,觉得应该有相应使用前题,但是前前后后翻翻,也没找到,奇了怪了~!