shared_ptr共享它所指向的对象,多个shared_ptr可以指向相同的对象, 在内部采用计数机制来实现
当新的shared_ptr与对象关联时候,引用计数加1
当shared_ptr超出作用域时,引用计数减1, 当引用计数变为0时,则释放该对象。
- shared_ptr计数指针又称共享指针
- 与unique_prt不同的是它可以共享数据
- shared_ptr创建了一个计数器与类对象所指的内存相关联
- Copy则计数器加一,销毁则计数器减一
- api为use_count()
shared_ptr初始化
// 1. 分配内存并且初始化
shared_ptr<Cat>p0(new Cat("莉莉"));
//2. c++11标准,效率更高,推荐使用
shared_ptr<Cat>p1(make_shared<Cat>("tom"));
//3. 用已经存在的地址初始化
Cat *cat = new Cat("jerry");
shared_ptr<Cat>p3(cat);
// 4. 用已经存在的shared_ptr p0初始化
shared_ptr<Cat>p0(new Cat("莉莉")); // 分配内存并且初始化
shared_ptr<Cat>p1(p0); // 用已经存在的shared_ptr p0初始化,引用计数+1
shared_ptr<Cat>p2(p0); // 用已经存在的shared_ptr p0初始化,引用计数+1
cout << "p0的引用计数:"<<p0.use_count() << endl;
cout << "p1的引用计数:"<<p0.use_count() << endl;
cout << "p2的引用计数:"<<p0.use_count() << endl;
shared_ptr使用
- 智能指针重载了* 和-> 操作符,可以像操作指针一样,操作shared_ptr
- use_count() 返回引用计数器的值
- unique() 如果use_count为1,则返回true,否则返回false
- get() 返回裸指针
- 不要用同一个对象,初始化多个shared_ptr
- 不要用shared_ptr管理不是new分配的内存
- 不支持指针的运算(+,-,++,--)
- shared_ptr支持赋值,坐值的shared_ptr将-1,右值的shared_ptr将+1
left = right;
int main() {
shared_ptr<Cat>pa0(new Cat("莉莉")); // 分配内存并且初始化
shared_ptr<Cat>pa1(pa0); // 用已经存在的shared_ptr p0初始化,引用计数+1
shared_ptr<Cat>pa2(pa0); // 用已经存在的shared_ptr p0初始化,引用计数+1
cout << "pa0的引用计数:"<<pa0.use_count() << endl;
shared_ptr<Cat>pb0(new Cat("汤姆"));
shared_ptr<Cat>pb1 = pb0;
cout << "pb0的引用计数:"<<pb0.use_count() << endl;
cout << "--------------------------" << endl;
pb1 = pa0;// 这行代码执行后,pa0的引用计数+1, pb1的引用计数-1
cout << "pa0的引用计数:"<<pa0.use_count() << endl;
cout << "pb0的引用计数:"<<pb0.use_count() << endl;
//下面这行代码执行后,pa0的引用计数+1, pb0的引用计数-1, 此时pb0的引用计数为0,其指向的对象也会被释放,调用其析构函数
pb0 = pa0;
cout << "--------------------------" << endl;
cout << "pa0的引用计数:"<<pa0.use_count() << endl;
cout << "pb0的引用计数:"<<pb0.use_count() << endl;
return 0;
}
image.png
shared_ptr更多细节
- 用 nullptr赋值给shared_ptr,将把引用计数-1,如果计数为0,将释放对象。
- std::move() 可以转移对原始指针的控制权,还可以将unique_ptr转换为shared_ptr
- reset()改变与资源的关联关系
pp.reset(); // 解除与资源的关系,资源的引用计数-1
pp.reset(new Cat("特斯拉")); // 解除与资源的关系,资源的引用计数-1, 关联新资源
- swap() 交换两个shared_ptr的控制权
void swap(shared_ptr<T>&right);
- shared_ptr也可以像普通指针一样,具有多态性质
- shared_ptr不是绝对安全,如果程序调用exit()退出, 全局的shared_ptr可以自动释放,但是局部的shared_ptr无法释放。
- shared_ptr 支持数组
- shared_ptr是线程安全的
- 如果unique_ptr可以解决的,就不要用shared_ptr,因为unique_ptr效率更高,占用的资源更少。
网友评论