智能指针 c++

155 阅读3分钟

智能指针-复制构造

设计具有指针成员的类时,首先需要决定的是该指针应提供什么行为。例如将一个指针复制到另一个指针时,两个指针指向同一个对象。当两个指针指向同一对象时,可能使用任一指针改变基础对象。类似地,很可能一个指针删除了一对象时,另一指针的用户还认为基础对象仍然存在。

大多数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;
};

版权声明:本文为CSDN博主「x-ghost」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:blog.csdn.net/MEIYOUDAO_J…