关闭

类的指针成员管理

686人阅读 评论(0) 收藏 举报

C++中,标准库的使用大大减少了现代C++程序中对指针的需要。然而,许多应用程序仍然需要使用指针,特别是在类的实现中,并且包含指针的类复制控制方面容易出错。

        具有指针成员的对象一般需要定义复制控制成员。如果依赖合成版本,会给类的用户增加负担。用户必须保证成员所指向的对象存在,只要还有指针指向该对象。为了管理这些具有指针成员的类,必须定义三个复制控制成员:复制构造函数、赋值操作符和析构函数。这些成员可以定义指针成员的指针型行为或值型行为,或者智能指针类(需要一个使用计数类配合)。

大多数C++类采用三种方法管理指针成员。

(1)指针成员采取常规指针型行为。复制指针时只复制指针中的地址,而不会复制指针指向的对象。这样的类具有指针的所有缺陷但无需特殊的复制控制。


常规指针类:

class HasPtr{
public: 
        HasPtr(int *p):ptr(p){}
        HasPtr(const HasPtr& Hp):ptr(Hp.ptr){}
        int get_ptr()const{retrun ptr;}
        void set_ptr(int *p){ptr=p;}
        int get_ptr_val()const {return *ptr;}
private:
        int *ptr;
}
如(出现悬垂指针!!!)
int *p=new int(10);
HasPtr ptr(p);//HasPtr points to same object as p does
delete p;//object pointed to by p is freed
ptr.set_ptr_val(0);//disaster: The object to which HasPtr points was freed!

(2)类可以实现所谓的“智能指针”(smart pointer)行为。指针所指的对象仍是共享的,但类能够防止悬垂指针(指向了不存在的对象的指针)。

         解决办法:为指向同一共享对象的指针引入了一个使用计数use count:记录指向共享对象的类对象数目。初始:新创建一个类对象,使用计数初值为1。

         即智能指针将一个计数器与类指向对象想关联起来。

使用计数类(有两种经典策略实现,另一种见:句柄类区别在于:类指针成员所指对象由谁直接关联(智能指针类:由使用计数类直接关联;句柄类:由句柄类自己直接关联。)):这里:定义一个单独的具体类:封装使用计数和相关指针。

class HasPtr;//智能指针类声明
class U_Ptr{ //定义为私有(class默认:private)
      friend class HasPtr;//友元     
      int *ip;
      size_t use; 
      U_Ptr(int *p):ip(p),use(1){}
      ~U_Ptr(){delete ip;}
}


智能指针类:

     class HasPtr{public: HasPtr(int *p):ptr(new U_Ptr(p)){} 
      HasPtr(const HasPtr& Hp):ptr(Hp.ptr){++ptr->use}  
      int get_ptr()const{retrun ptr;} 
      void set_ptr(int *p){ptr=p;}
      int get_ptr_val()const {return *ptr;}
      HasPtr& operator=(const HasPtr&rhs) 
      {
             ++rhs.ptr->use;//可防止自身复制 
             if(--ptr->use==0)delete ptr; 
             ptr=rhs.ptr; 
             return *this; 
       }
       ~HasPtr(){if(ptr->use==0)delete ptr;}
private: U_Ptr *ptr;
};


(3)类采取值型行为。将指针成员所指基础值的副本给每个对象。每个指针所指向的对象是唯一的,由每个类对象独立管理。
使指针成员表现的想一个值(指针的值型行为),复制值型对象时,会得到一个不用的新副本。即复制指针所指向的对象,而不是复制指针本身。


值型类:

class HasPtr{
public:
       HasPtr(const int *p):ptr(new int(*p)){}
       HasPtr(const HasPtr& orig):ptr(new int (*orig.ptr)){}
       HasPtr& operator=(const HasPt&rhs)
       {
              *ptr=*rhs.ptr;
               return 0;
       }
       int get_ptr_val()const{return *ptr;}
       int* get_ptr()const{return ptr;}
       void set_ptr(int *p){ptr=p;}
       ~HasPtr(){delete ptr;}
private:
       int *ptr; 
};













   
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:341533次
    • 积分:3105
    • 等级:
    • 排名:第11097名
    • 原创:43篇
    • 转载:13篇
    • 译文:0篇
    • 评论:66条
    最新评论