0
点赞
收藏
分享

微信扫一扫

智能指针(四shared_ptr)

kolibreath 2022-01-13 阅读 110

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;
}
举报

相关推荐

0 条评论