智能指针shared_ptr实现

智能指针:它的一种通用实现方法是采用引用计数的方法。智能指针将一个计数器与类指向的对象相关联,引用计数跟踪共有多少个类对象共享同一指针。

    每次创建类的新对象时,初始化指针并将引用计数置为1;
    当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相应的引用计数;
    对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数;这是因此左侧的指针指向了右侧指针所指向的对象,因此右指针所指向的对象的引用计数+1;
    调用析构函数时,构造函数减少引用计数(如果引用计数减至0,则删除基础对象)。
    实现智能指针有两种经典策略:一是引入辅助类,二是使用句柄类。


namespace smart

{
	// 引用计数类.

	class smart_count
	{
	public:

		smart_count(int c = 0) : use_count(c) {}

		~smart_count() {}

		// 增加引用计数, 并返回计数值.

		int addref() {
				return ++use_count;
			}

		// 减少引用计数, 并返回计数值.

		int release() {
				return --use_count;
			}



	private:

		// 计数变量.

		int use_count;

	};



	// 智能指针.

	template<class T>

	class
		smart_ptr

	{

	public:

		// 构造指针, 并使引用计数置为1.

		explicit
			smart_ptr(T* ptr) : p(ptr), u(new smart_count(1))

		{}

		// 构造空指针.

		explicit
			smart_ptr() : p(NULL), u(NULL)

		{}

		// 智能指针析构.

		~smart_ptr(void)

		{

			// 如果引用计数等于0, 则删除数据和引用计数, 并置p为NULL.

			// 此处需要注意的是, 共用的u并未置为 NULL, 在其它指针析构

			// 时, p为NULL, 则不会重复delete.

			if
				(p && u->release() <= 0)

			{

				delete p;

				delete u;
				p = NULL;

			}

		}

		// 智能指针拷贝构造函数.

		smart_ptr(const smart_ptr<T>& t)

		{

			p = t.p;

			u = t.u;

			if(u) // 必须判断空值.

			{

				u->addref(); // 增加引用计数.

			}

		}

		// 指针赋值.

		void operator= (smart_ptr<T>& t)

		{

				// 首先将引用计数减1, 然后再判断是否小于0, 如果小于0, 则delete.          

				if(p && u->release() <= 0)

				{

					delete p;

					delete u;

				}

				// 直接赋值.

				p = t.p;

				u = t.u;

				if(u)  // 必须判断空值.

				{

					u->addref(); // 增加引用计数.

				}

			}

		// 重载->操作和*操作符.

		T *operator-> (void) {
			return p;
		}

		T& operator *(void) {
			return *p;
		}

		// 重载!操作符.

		bool operator! () const
		{
				return !p;
			}



		// 重载指针bool值操作符.

		typedef smart_ptr<T> this_type;

		typedef T * this_type::*unspecified_bool_type;

		operator unspecified_bool_type() const
		{
			return !p ? 0 : &this_type::p;
		}

		// 得到原指针.

		T* get() {
			return p;
		}

		void reset(T* ptr)

		{

				// 首先将引用计数减1, 然后再判断是否小于0, 如果小于0, 则delete.          

				if (p && u->release() <= 0)

				{

					delete p;

					delete u;

				}

				// 赋值, 如果是NULL, 则不创建引用计数.

				p = ptr;

				if(p)
                 u = new smart_count(1);

				else
					u = NULL;

			}
		
		void reset(smart_ptr<T>& t)

		{
				// 首先将引用计数减1, 然后再判断是否小于0, 如果小于0, 则delete.          

				if
					(p && u->release() <= 0)

				{

					delete p;

					delete u;

				}

				// 赋值.

				p = t.p;

				u = t.u;
								
				if(u)  // 必须判断空值.

				{

					u->addref(); // 增加引用计数.

				}

			}
		
	private:

		T* p;

		smart_count* u;

	};

	
	// 重载==操作符.

	template<class T, class U> inline
		bool  operator==(smart_ptr<T> & a, smart_ptr<U> & b)

	{
			return a.get() == b.get();

		}


	// 重载!=操作符.

	template<class T, class U> inline
		bool  operator!=(smart_ptr<T> & a, smart_ptr<U> & b)

	{

			return a.get() != b.get();

		}

}

另外一种实现方式:
3, 智能指针的实现

      下面是一个基于引用计数的智能指针的实现,需要实现构造,析构,拷贝构造,=操作符重载,重载*-和>操作符。

[cpp] view plain copy
template <typename T>  
class SmartPointer {  
public:  
    //构造函数  
    SmartPointer(T* p=0): _ptr(p), _reference_count(new size_t){  
        if(p)  
            *_reference_count = 1;   
        else  
            *_reference_count = 0;   
    }  
    //拷贝构造函数  
    SmartPointer(const SmartPointer& src) {  
        if(this!=&src) {  
            _ptr = src._ptr;  
            _reference_count = src._reference_count;  
            (*_reference_count)++;  
        }  
    }  
    //重载赋值操作符  
    SmartPointer& operator=(const SmartPointer& src) {  
        if(_ptr==src._ptr) {  
            return *this;  
        }  
        releaseCount();  
        _ptr = src._ptr;  
        _reference_count = src._reference_count;  
        (*_reference_count)++;  
        return *this;  
    }  
  
    //重载操作符  
    T& operator*() {  
        if(ptr) {  
            return *_ptr;  
        }  
        //throw exception  
    }  
    //重载操作符  
    T* operator->() {  
        if(ptr) {  
            return _ptr;  
        }  
        //throw exception  
    }  
    //析构函数  
    ~SmartPointer() {  
        if (--(*_reference_count) == 0) {  
            delete _ptr;  
            delete _reference_count;  
        }  
    }  
private:  
    T *_ptr;  
        size_t *_reference_count;  
        void releaseCount() {  
        if(_ptr) {  
            (*_reference_count)--;  
                if((*_reference_count)==0) {  
                    delete _ptr;  
                    delete _reference_count;  
                }  
        }  
        }  
};  
  
int main()   
{  
    SmartPointer<char> cp1(new char('a'));  
    SmartPointer<char> cp2(cp1);  
    SmartPointer<char> cp3;  
    cp3 = cp2;  
    cp3 = cp1;  
    cp3 = cp3;  
    SmartPointer<char> cp4(new char('b'));  
    cp3 = cp4;  
}  



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值