智能指针 smart pointer

来源:互联网 发布:vehicleblackbox淘宝 编辑:程序博客网 时间:2024/05/18 03:37

                                                                                                  智能指针-复制构造

       设计具有指针成员的类时,首先需要决定的是该指针应提供什么行为。例如将一个指针复制到另一个指针

时,两个指针指向同一个对象。当两个指针指向同一对象时,可能使用任一指针改变基础对象。类似地,很可

能一个指针删除了一对象时,另一指针的用户还认为基础对象仍然存在。


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

        1.指针成员采取常规指针型行为。(只复制指针本身,不复制指针所指的空间)

        2.类采取值型行为。(复制指针同时,复制指针所指的空间,双份空间)

        3.类可以实现所谓的的“智能指针”行为。(指针所指向的对象是共享的(复制

           指针,他们指向同一份空间),但类防止“垂悬指针”。)

指针成员采取常规行为:

class HasPointer{public:        HasPointer(int *p, int i): ptr(p), val(i) {}public:       int * get_ptr() const { return ptr;}       int get_val() const { return val;}        void set_ptr( int * p) { ptr = p;}       void set_val( int i) { val = i;}       int get_ptr_val() const { return *ptr;}       void set_ptr_val( int i) { *ptr = i;}private:       int *ptr;       int val;};

指针成员常规行为客户端:

void main(){        int *pObj = new int(20);        HasPointer ptr1(pObj,10);        /* 使用默认复制/赋值构造函数,即复制一个对象将复制它的成员 */        HasPointer ptr2(ptr1);        pObj?delete pObj:NULL;        ptr2.set_ptr_val(1);                /* objPtr1和objPtr2中的指针ptr指向相同的内存位置,且值相同         ,这样处理会使得ptr具有普通指针的所有缺陷即无法避免垂悬指        针等,如以上的ptr2.set_ptr_val(1)就会很危险。        */}

类采取值型行为:

class HasPointer{public:       HasPointer(const int &p, int i): ptr(new int(p)), val(i) {}       /* 复制构造将不再复制指针,它将分配一个新的int 对象,并初始化与被          复制对象相同的值,每个对象拥有自己的副本 */       HasPointer(const HasPointer &orig):ptr(new int(*orig.ptr)),val(orig.val){}       HasPointer& operator=(const HasPointer& hpo){               *ptr = *hpo.ptr;               val = hpo.val;               return *this;       }       ~HasPointer(){delete ptr;}public:        int * get_ptr() const { return ptr;}        int get_val() const { return val;}        void set_ptr( int * p) { ptr = p;}        void set_val( int i) { val = i;}        int get_ptr_val() const { return *ptr;}        void set_ptr_val( int i) { *ptr = i;}private:        int *ptr;        int val;}// 相应的模板类template< typename T>class ValueHasPU{public:ValueHasPU(const T &ptemp, int val):pData(new T(ptemp)),iVal(val){}ValueHasPU(const ValueHasPU & othor):pData(new T(*othor.pData)),iVal(othor.iVal){}ValueHasPU& operator=(const ValueHasPU & rhs){*pData = *rhs.pData;iVal = rhs.iVal;return *this; }; ~ValueHasPU(){ pData?delete pData:NULL;}private:T * pData;int iVal;};

智能指针方法: 定义智能指针的通用技术是,采用一个“使用计数”。

/*    定义一个单独的具体类用以封闭使用计数和相关指针,同时这个单独类中    成员均为私有的,只有其友元类的成员可以访问它的成员。*/class u_pointer{        friend class HasPointer;        u_pointer(int *p): ip(p), use(1) {}        ~u_pointer() {ip?delete ip,ip=NULL:NULL;}        int * ip;        size_t use;}class HasPointer{public:        HasPointer(int *p, int i): ptr(new u_pointer(p)), val(i) {}        HasPointer(const HasPointer &orig): ptr(orig.ptr), val(orig.val) { ptr->use++; }        HasPointer & operator= (const HasPointer &hpo){                /* 在减少左操作数的使用计数之前使hpo的使用计数加1,从而防止自身赋值。                   如果是自身赋值,加1之后立即减1 */                ++hpo.ptr->use;                --ptr->use?delete ptr;NULL;                /* 开始赋值 */                ptr=hpo.ptr;                val=hpo.val;                return *this;        }        ~HasPointer(){                 if(0==ptr->use)                        ptr?delete ptr,ptr=NULL:NULL;        }public:       int * get_ptr() const { return ptr->ip;}       int get_val() const { return val;}        void set_ptr( int * p) { ptr->ip = p;}       void set_val( int i) { val = i;}       int get_ptr_val() const { return *ptr->ip;}       void set_ptr_val( int i) { *ptr->ip = i;}private:       u_pointer * ptr;       int val;};

相应的模板类

template <typename T> class HasPU;template<typename T>class pHas{friend class HasPU<T>;pHas(T *p):pData(p),iUse(1){}~pHas(){pData?delete pData,pdate=NULL:NULL;}T *pData;unsigned int iUse;};template<typename T>class HasPU{public:HasPU(T * p,int val):pPointor(new pHas<T>(p)),iVal(val){}HasPU(const HasPU& other){++other.pPointor->iUse;pPointor= other.pPointor;iVal=other.iVal; } HasPU & operator=(const HasPU& oHasPU) {++oHasPU.pPointor->iUse;if (0==--pPointor->iUse)  {pPointor->data?delete pPointor->pData:NULL;}pPointor = oHasPU.pPointor;iVal = oHasPU.iVal;return *this; } ~HasPU(){pPointor->iUse?delete pPointor:NULL;}private: pHas<T> * pPointor; int iVal;};

0 0
原创粉丝点击