C++基础之管理指针成员

通常复制指针时,只复制了指针中的地址。而不会复制指针指向的对象。
C++中管理指针的三种方法:
1、指针成员采取常规指针型行为。这样的类具有指针的所有缺陷但无需特殊的复制控制;
2、类可以实现所谓的智能指针行为。指针所指向的对象是共享的,但类能够防止悬垂指针;
3、类采取值型行为。指针指向的对象是唯一的,由每个类对象独立管理。

一、悬垂指针
因为类直接复制指针,会使用户面临潜在问题:HasPtr保存着给定指针,用户必须保证只要HasPtr对象存在,该指针指向的对象就存在:

int *ip=new int(42);
HasPtr ptr(ip,10);
delete ip;
ptr.set_ptr_val(0);

其中ip和ptr中的指针指向同一个对象,删除了该对象,ptr中的指针不再指向有效对象。但是没有办法得知对象已经不存在了。

二、智能指针类
智能指针的通用技术是使用计数(引用计数)。智能指针类将一个计数器与类指向的对象相关联,使用计数跟踪该类有多少对象共享同一指针。使用计数为0时,删除对象。
每创建类的新对象时,初始化指针并将使用计数置为1,。当对象作为另一个对象的副本而创建时,复制构造函数复制指针并增加与之相应的使用计数的值。对一个对象赋值时,赋值操作符减少左操作数所指对象的使用计数的值(若使用计数减到0,就删除对象),并增加右操作数所指对象的使用计数的值,最后调用析构函数时,析构函数减少使用计数的值,如果使用计数减到0,则删除基础对象。
1、使用计数类

class U_Ptr{
      friend class HasPtr;
      int *ip;
      size_t use;
      U_ptr(int *p) : ip(p), use(1) {}
      ~U_Ptr()  {delete ip;}
};

将HasPtr类设为友元,使其成员可以访问U_ptr的成员。U_Ptr保存指针和使用计数,每个 HasPtr对象将指向一个U_Ptr对象,使用计数将跟踪指向每个U_Ptr对象的HasPtr对象的数目,构造函数还将使用计数设为1,表示一个HasPtr对象指向这个U_Ptr对象。

class HasPtr{
public:
    HasPtr(int *p,int i):ptr(new U_Ptr), val(i) {}
    HasPtr(const HasPtr &orig):
       ptr(orig.ptr), val(orig.val) {++ptr->use;}
    HasPtr& operator=(const HasPtr&);
    ~HasPtr() {if(--ptr->use==0) delete ptr;}
private:
U_Ptr *ptr;
int val;
};

新的HasPtr类保存一个指向U_Ptr对象的指针,U_Ptr对象指向实际的int基础对象。复制构造函数从形参复制成员并增加使用计数的值,复制构造函数执行完毕后,新创建对象与原有对象指向同一U_Ptr对象,该U_Ptr对象的使用计数加一。
析构函数将检查U_Ptr基础对象的使用计数,若计数为0,则这是最后一个指向该U_Ptr对象的HasPtr对象,此时,HasPtr析构函数删除其U_Ptr指针,该操作将引起对U_Ptr析构函数的调用,U_Ptr析构函数删除int基础对象。
注:HasPtr的用户无需担心悬垂指针,只要他们让HasPtr类负责释放对象,HasPtr类将保证只要有指向基础对象的HasPtr对象存在,基础对象就存在。

三、值型类
将指针成员所指基础值的副本给每个对象,复制构造函数分配新元素并从被复制对象处复制值,赋值操作符撤销所保存的原对象并从右操作数向左操作数复制值,析构函数撤销对象。
复制构造函数不再复制指针,他将分配一个新的int对象,并初始化该对象以保存与被复制对象相同的值,每个对象都保存属于自己的int值得不同版本。因为每个对象保存自己的副本,所以析构函数将无条件删除指针。赋值操作符不需要分配新对象,他只是必须记得给其指针所指向的对象赋新值,而不是给指针本身赋值。即改变的是指针所指向的值,而不是指针。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值