智能指针(四shared_ptr)

本文详细介绍了C++智能指针shared_ptr的工作原理,包括其特点、如何使用引用计数管理内存、构造与赋值操作、所有权转移及引用计数的管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

shared_ptr


shared_ptr特点:

  • 不能隐式构造
  • 不能将同一个裸指针赋值给多个智能指针
  • 允许并且可以进行拷贝构造和等号运算符重载
  • 每个shared_ptr对象在内部指向两个内存位置:指向对象的指针;用于控制引用计数的指针

共享所有权如何使用引用计数:

  • 当新的shared_ptr对象与指针相关联时,则在其构造函数汇总,将与此指针相关量的引用计数加1.
  • 当任何shared_ptr对象超出作用域时,则在其析构函数中,它将关联指针的引用计数减1
  • 如果引用计数减为0,则表示没有shared_ptr对象与原始指针关联,在这种情况下,它就会使用delete函数来释放该内存。
  • shared_ptr对象的所有权可以转移
    创建shared_ptr对象:
    int* p = new int(99);
	Mshared_ptr<int>s_p1(p);

    Mshared_ptr<int>s_p1=make_shared<int>();

上述两种方式都可创建对象,但是使用make_shared会开辟了两块内存:一块存储int值,一块存储引用计数。而new只能开辟存放int值的空间
引用计数:

s_p1.use_count();//初始值为1

拷贝构造函数:

    Mshared_ptr(const Mshared_ptr& src)
	{
	    //如果此shared_ptr对象红黑树中没有找到,则插入进去,并没有重新开辟空间
		if (_count.end() == _count.find(_ptr))
		{
			_count.insert(make_pair(src._ptr, 1));
		}
		_ptr = src._ptr;
		_count[_ptr]++;//引用计数加一
	}

等号运算符重载:

Mshared_ptr& operator=(const Mshared_ptr& src)
	{
		if (this == &src)//防止自赋值
		{
			return *this;
		}
		if (_count.end() == _count.find(src._ptr))
		{
			_count.insert(make_pair(src._ptr, 1));
		}
		_ptr = src._ptr;
		_count[_ptr]++;
		return *this;
	}

减少与原始指针相关联的对象:

	void reset()
	{
		if (unique())
		{
			delete _ptr;
		}
		else
		{
			_count[_ptr]--;
		}
		_ptr = NULL;
	}

判断是否还有与原始指针关联的对象:

bool unique()
	{
		if (_count.end() == _count.find(_ptr) || _count[_ptr] == 1)
		{
			return true;
		}
		return false;
	}

返回引用计数:

   int use_count()
	{
		if (_count.end() == _count.find(_ptr))
		{
			return 1;
		}
		return _count[_ptr];
	}

获取内部指针:

	T* get()
	{
		return _ptr;
	}

完整代码示例:

emplate<typename T>
class Mshared_ptr
{
public:
	explicit Mshared_ptr(T* ptr = NULL)
	{
		_ptr = ptr;
	}
	Mshared_ptr(const Mshared_ptr& src)
	{
		if (_count.end() == _count.find(_ptr))
		{
			_count.insert(make_pair(src._ptr, 1));
		}
		_ptr = src._ptr;
		_count[_ptr]++;
	}
	Mshared_ptr& operator=(const Mshared_ptr& src)
	{
		if (this == &src)
		{
			return *this;
		}
		if (unique())
		{
			delete _ptr;
		}
		else
		{
			_count[_ptr]--;
		}
		if (_count.end() == _count.find(src._ptr))
		{
			_count.insert(make_pair(src._ptr, 1));
		}
		_ptr = src._ptr;
		_count[_ptr]++;
		return *this;
	}
	~Mshared_ptr()
	{
		if (unique())
		{
			delete _ptr;
		}
		else
		{
			_count[_ptr]--;
		}
	}
	T* get()
	{
		return _ptr;
	}
	void reset()
	{
		if (unique())
		{
			delete _ptr;
		}
		else
		{
			_count[_ptr]--;
		}
		_ptr = NULL;
	}
	bool unique()
	{
		if (_count.end() == _count.find(_ptr) || _count[_ptr] == 1)
		{
			return true;
		}
		return false;
	}
	int use_count()
	{
		if (_count.end() == _count.find(_ptr))
		{
			return 1;
		}
		return _count[_ptr];
	}
	T&operator*()
	{
		return *_ptr;
	}
	T*operator->()
	{
		return _ptr;
	}
	operator bool()
	{
		return _ptr != NULL;
	}
	//template<typename Ty>
	//friend class Mweak_ptr<Ty>
private:
	T* _ptr;
	static map<T*,int> _count;
};

template<typename T>
map<T*,int> Mshared_ptr<T>::_count = map<T*,int>();

int main()
{
	int* p = new int(99);
	Mshared_ptr<int>s_p1(p);
	//Mshared_ptr<int>s_p2(p);

	Mshared_ptr<int>s_p3 = s_p1;
	Mshared_ptr<int>s_p4;
	s_p4 = s_p1;
	cout << *s_p1 << endl;
	cout << *s_p3 << endl;
	cout << *s_p4 << endl;
	Mshared_ptr<int>s_p5=move(s_p4);//转移s_p4的所有权给s_p5
	//s_p4.reset();
	//s_p4.get();
	//s_p4[];
	//s_p4.unique();//判断当前的引用计数是否为1,独有的
	cout << s_p3.use_count() << endl;
	cout << s_p4.use_count() << endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值