std::shared_ptr使用方法和注意事项

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

这样就可以正常析构了

参考:

智能指针shared_ptr的用法

std::shared_ptr<T>::reset

https://en.cppreference.com/w/cpp/memory/shared_ptr

http://www.cplusplus.com/reference/

原文地址:https://www.cnblogs.com/gwzz/p/13999572.html