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版权协议,转载请附上原文出处链接和本声明。