C++智能指针(3)—— shared_ptr

1、shared_ptr

强智能指针
①不允许隐式构造
②不能使用同一个裸指针赋值,或使用同一个裸指针初始化多个shared_ptr

//程序崩溃
void text01()
{
	int* p = new int(11);
	shared_ptr<int> s_p (p);
	shared_ptr<int> s_p1(p);
	cout << *p << endl;
	cout << *s_p << endl;
	cout << *s_p1 << endl;
}
int main()
{
	text01();
	return 0;
}

③允许拷贝构造,允许等号运算符重载

2、shared_ptr加了引用计数器

因为加了引用计数,所以允许拷贝构造,允许等号运算符重载
加了引用计数,统计被引用的个数,析构的时候减减,不会直接delete。
内部用静态映射表,然后在映射表里面,当我们要进行拷贝构造或者等号运算符重载的时候,把指针放到映射表中,统计它的次数,当进行拷贝构造或者等号运算符重载的时候引用计数++,当析构的时候引用计数–。

3、shared_ptr的部分源码


#include<map>
using namespace std;

template<typename T>
class Mshared_ptr
{
public:
	explicit Mshared_ptr(T* ptr = nullptr)//explicit防止隐式构造
		:_ptr(ptr)
	{}

	//Munique_ptr(Munique_ptr& src) = delete;

	///Munique_ptr& operator=(Munique_ptr& src) = delete;

	Mshared_ptr(Mshared_ptr& src)
	{
		/*
		//判断插入是否成功
		if (_count.insert(make_pair(_ptr, 2)).second == 0)
		{
			_count[_ptr]++;
		}*/

		_count.insert(make_pair(_ptr, 1));
		_count[_ptr]++;

		_ptr = src._ptr;
	}

	Mshared_ptr& operator=(Mshared_ptr&& src)
	{
		if (_ptr == src._ptr)
		{
			return *this;
		}

		if (unique())
		{
			_count.erase(_ptr);
			delete _ptr;
		}
		else
		{
			_count[_ptr]--;
		}
		_ptr = src._ptr;
	}



	~Mshared_ptr()
	{
		if (unique())
		{
			_count.erase(_ptr);
			delete _ptr;
		}
		else
		{
			_count[_ptr]--;
		}
	}

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

	T* release()
	{
		T* tmp = _ptr;
		if (unique())
		{
			_count.erase(_ptr);
			//delete _ptr;
		}
		else
		{
			_count[_ptr]--;
		}
		_ptr = NULL;
		return tmp;
	}

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

	T& operator*()
	{
		return *_ptr;
	}

	T* operator->()
	{
		return _ptr;
	}

	operator bool()
	{
		return _ptr != NULL;
	}


private:
	static map<T*, int>* _count;
	T* _ptr;
};

4、智能指针交叉引用

class B;
class A
{
public:
	A()
	{
		cout << "A" << endl;
	}
	~A()
	{
		cout << "~A" << endl;
	}
	shared_ptr<B> _ptr_b;
};
class B
{
public:
	B()
	{
		cout << "B" << endl;
	}
	~B()
	{
		cout << "~B" << endl;
	}
	shared_ptr<A> _ptr_a;
};
int main()
{
	shared_ptr<A>a_p(new A());
	shared_ptr<B>b_p(new B());
	a_p->_ptr_b = b_p;
	b_p->_ptr_a = a_p;
	return 0;
}

程序运行结果:
在这里插入图片描述
上面的运行结果只有A和B的构造,并没有对象的析构,原因是:
A里面有一个B的智能指针,B里面有一个A的智能指针,然而他们互相把自己的值赋给对方,造成交叉引用无法析构。
源头是因为shared_ptr有引用计数,所以就需要weak_ptr,weak_ptr见下一期"C++智能指针(4)—— weak_ptr"。


版权声明:本文为m0_54355780原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。