shared_ptr简介
shared_ptr是一个**标准的共享所有权的智能指针。**它允许多个指针指向同一个对象,定义在memory文件内,命名空间为std。
shared_ptr最初实现于Boost库中,后由C++11引入到C++ STL。
shared_ptr利用引用计数的方式实现了对所管理的对象的所有权的分享,即:
- 允许多个shared_ptr共同管理同一个对象。
shared_ptr是为了解决auto_ptr在对象所有权上的局限性而提出的(auto_ptr是独占的),使用引用计数的机制的同时,提供了可共享所有权的智能指针。这种额外的机制,需要额外的代价:
- shared_ptr对象除了包括一个所拥有的对象的指针外,还必须包括一个引用计数代理对象的指针。
- 时间上,开销主要消耗在初始化和拷贝操作上。
shared_ptr的使用
shared_ptr多个指针指向同一个对象,每一个shared_ptr的拷贝都会指向相同的内存。
- 每使用一次,内部的引用计数就加一;
- 每析构一次,内部的引用次数就减一;当减为0时,将会自动删除所指向的堆内存。
shared_ptr内部的引用计数是线程安全的,但是对象的读取需要加锁。
- 初始化。智能指针是一个模板类,可以指定类型,传入指针并通过构造函数初始化。也可以通过make_shared函数初始化。不能将指针直接赋值给一个智能指针,因为一个是类,一个是指针。例如,
的写法就是错误的。shared_ptr<int> p = new int(1);
- 拷贝与赋值。拷贝操作使得对象的引用计数增加1,赋值操作使得原对象引用计数减一,当计数为0是,自动释放内存。
- get函数用于获取原始指针。
- 不能用一个原始指针初始化多个shared_ptr,否则会造成二次释放同一内存。
- 注意避免循环引用。shared_ptr的一个最大的陷阱就在于循环引用,循环、循环引用将会导致堆内存无法正确释放,从而导致内存泄漏。
#include <iostream>
#include <memory>
int main()
{
int a = 10;
std::shared_ptr<int> ptra = std::make_shared<int>(a);
std::shared_ptr<int> ptra2(ptra); //copy
std::cout << ptra.use_count() << std::endl;
int b = 20;
int *pb = &a;
//std::shared_ptr<int> ptrb = pb; //error
std::shared_ptr<int> ptrb = std::make_shared<int>(b);
ptra2 = ptrb; //assign
pb = ptrb.get(); //获取原始指针
std::cout << ptra.use_count() << std::endl;
std::cout << ptrb.use_count() << std::endl;
}
参考文章:
C++11中智能指针的原理、使用、实现