1.创建
有三种方式,分别为构造函数、std::make_shared<T>辅助函数和reset方法
1.1构造函数
就像普通的类一样,需要在定义变量的时候,使用new 对象作为输入参数。但是这种方法需要两次申请内存空间,第一次是new,第二是智能对象本身需要申请的内存。
1.2std::make_shared<T>辅助函数
因为是在<memory>下的一个模板函数,实现了同时申请内存,推荐使用。例如
auto p = std::make_shared<Person>("Chris");
表示创建了智能指针对象,对Person对象进行管理,该Person对象的构造函数的输入参数为字符串"Chris"。此时,可以使用auto自动推导。
1.3reset
就是让智能指针对象重新指向一个新的对象,而对原来所指对象的计数减1。
在进行reset(new xxx())重新赋值时,智能指针对象首先是生成新的对象,然后将指针对象的引用计数减1(当然,若方法计数为0,则析构),然后将新对象的指针交给智能指针保管。
例如:
std::shared_ptr<Person> p1(new Person(1));// Person(1)的引用计数为1
p1.reset(new Person(3)); // 此时,p1先进行new Person(3),
// 然后p1会对Persion(1)的引用计数减1。此处为0,就会析构Person(1)。最后管理新的对象Person(3)
2.获取原始指针
std::shared_ptr<int> p(new int(5));
int *pInt = p.get()
3.指定删除器
默认删除器不支持数组对象,所以需要指定删除器。
4.注意事项
- 原始指针只能初始化一个shared_ptr;
- 在函数实参中不创建shared_ptr;
- 禁止通过shared_from_this()返回this,这样做可能造成二次析构;
- 避免循环引用(智能指针最大的一个陷阱是循环引用)
解决方法是使用weak_ptr;就是在相互调用的类中使用std::weak_ptr<A> wpa和std::weak_ptr<B> wpb,而不使用std::shared_ptr<A>和std::shared<B>,示例代码如下:
struct AStruct; struct BStruct; struct AStruct { std::weak_ptr<BStruct> bPtr; ~AStruct() { std::cout << "AStruct is deleted!" << std::endl; } }; struct BStruct { std::weak_ptr<AStruct> aPtr; ~BStruct() { std::cout << "BStruct is deleted!" << std::endl; } }; void testLoopReference() { std::shared_ptr<AStruct> spA(new AStruct); std::shared_ptr<BStruct> spB(new BStruct); spA->bPtr = spB; spB->aPtr = spA; }
这样就可以正常析构了
参考: