一步一步写STL:定制boost::shared_ptr

       某知名大师说过:自从有了智能指针,上一次发生内存泄露还是在2004年当实习生的时候!

       由此可见智能指针威力无穷,竟让他8年没发生过内存泄露,我们上一篇给出了auto_ptr的实现方案,今天给出shared_ptr和实现版本,在新标准中auto_ptr已经不复存在了(其实存在不存在也没什么关系,你想用的话随时可以自己写一个啊)

取而代之的是引入了boost的shared_ptr智能指针和其他三个,这是一个引用计数型的类指针,相比auto_ptr。他有一个至关重要的优点——可以当成类型放入容器,这点auto_ptr是办不到的!

 

根据Effective C++上对shared_ptr的描述,我们很容易想到他的内部实现,以下是我写的实现版本:

template<class _Ty>
class shared_ptr
{
	typedef _Ty  element_type;
	typedef _Ty* pointer;
private:
	_Ty* _ptr;
	static std::size_t n_count;
	static void change_count_num(bool )throw();

public:

	explicit shared_ptr(pointer p=0 )throw()
		:_ptr(p)
	{//构造函数 只能被显示初始化
		shared_ptr::change_count_num(true);
		 //std::cout<<shared_ptr::n_count<<std::endl;
	}

	shared_ptr(const shared_ptr &sPtr)throw()
		:_ptr( sPtr.get() )
	{//复制构造函数
		shared_ptr::change_count_num(true);
		 //std::cout<<shared_ptr::n_count<<std::endl;
	}

	shared_ptr& operator= (const shared_ptr &sPtr)throw()
	{//赋值操作符
		_ptr = sPtr.get();
		shared_ptr::change_count_num(true);
		 //std::cout<<shared_ptr::n_count<<std::endl;
		return *this;
	}

	template<typename other>
	shared_ptr(const shared_ptr<other> &sPtr)throw()
		:_ptr( sPtr.get() )
	{//重载模版复制函数,用于实现继承体系中的多态性
		shared_ptr::change_count_num(true);
	}

	template<typename other>
	shared_ptr& operator= (const shared_ptr<other> &sPtr)throw()
	{//赋值操作符
		_ptr = sPtr.get();
		shared_ptr::change_count_num(true);
		return *this;
	}

	~shared_ptr()throw()
	{//析构函数,判断计数是否为0
		if(shared_ptr::n_count == 0)
		{
			delete _ptr;
			_ptr = 0;
		}
		 
	shared_ptr::change_count_num(false);	}

	pointer get()const throw()
	{//get器,RAII的设计原则,参见Effective C++
		return _ptr;
	}

	void release()throw()
	{//释放掉对其的拥有,并置于0
		_ptr = 0;
		shared_ptr::change_count_num(false);
	}

	pointer operator-> ()throw(){
		return _ptr;
	}
	element_type operator* (){
		return *_ptr;
	}
	operator bool()const throw(){
		return _ptr;
	}

};

template<typename _Ty>
 std::size_t shared_ptr<_Ty>::n_count = -1;

 template<typename _Ty>
 void shared_ptr<_Ty>::change_count_num (bool flag)
 {
	 flag? ++shared_ptr<_Ty>::n_count : --shared_ptr<_Ty>::n_count;
 }

其中对于引用计数的实现,我使用的static成员,用于标识该类的计数,值得说明的主要就是在所有构造函数和赋值函数 使用静态函数change_count_num,传递true表示加1,false表示减1,并在析构函数执行相应的操作,相对较简单,已基本测试!其中注释的地方为测试计数使用的输出语句!

 

 

 

 

 


 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
std::shared_ptrC++标准库中的一个智能指针类,用于管理动态分配的资源。它具有引用计数机制,可以实现多个指针共享同一个对象的所有权。 在给std::shared_ptr赋值时,有三种方式可以使用: 1) 拷贝赋值:使用一个std::shared_ptr初始化另一个std::shared_ptr,这将导致引用计数加1。 2) 移动赋值:使用std::make_shared或者直接赋值一个临时创建的std::shared_ptr,这将导致原来的std::shared_ptr失去对资源的所有权,引用计数转移。 3) 使用std::move:将一个std::unique_ptr移动给std::shared_ptr,这将导致原来的std::unique_ptr失去对资源的所有权,引用计数转移。 对于std::shared_ptr的成员函数功能,具体可以参考STL的文档或笔记。 关于std::shared_ptr的初始化,当使用裸指针初始化std::shared_ptr时,如果指针为nullptr,则std::shared_ptr的_M_ptr和_M_refcount都将为nullptr;否则,将分配内存并初始化控制块。 所以,std::shared_ptr可以用于管理动态分配的资源,并且可以共享资源的所有权。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [std::shared_ptr 详解](https://blog.csdn.net/baidu_31541363/article/details/95802210)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [[STL] std::shared_ptr笔记](https://blog.csdn.net/weixin_38734472/article/details/126486549)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值