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