我必须在我自己的析构函数中手动重置shared_ptrs吗?

Do I have to manually reset shared_ptrs in my own destructors?

本文关键字:shared ptrs 我自己 自己的 析构函数      更新时间:2023-10-16

假设我有一个类

class A {
public: // I know, I know...
    shared_ptr<string> aString;
};

我必须有一个像

这样的析构函数吗?
~A() {
    aString.reset();
}

确保所有权得到适当的重新分配?我做了一些测试,似乎我不需要-即,当a的实例超出范围或被删除(或重置,如果我通过shared_ptr引用它),字符串也被删除(我玩了一个更复杂的例子来证实这一点)。但是,这可能是特定于我正在使用的编译器的实现(clang-700.0.72)。

我的问题是:这总是情况下,还是更好地显式重置这些实例,就像我要删除任何其他哑指针?

不,您不需要这样做。作为普通析构函数的一部分,类的每个成员将依次销毁。智能指针的析构函数将负责必要的计算,在本例中是隐式的reset

不,这是智能指针的主要目的:自动管理内存

shared_ptr的析构函数将自动减少引用计数,如果它达到0,将调用删除器。

如果不提供析构函数,则会生成一个默认的析构函数:

§12.4.4如果类没有用户声明的析构函数,则隐式地声明析构函数为默认值

类的销毁将保证成员的销毁。

§12.4.8在执行析构函数体并销毁在析构函数体中分配的任何自动对象之后,类X的析构函数调用X的直接非变量非静态数据成员(…)的析构函数

对于shared_ptr则意味着:

§20.8.2.2.2.1

~shared_ptr();

效应:

  • 如果*this为空或与另一个shared_ptr实例共享所有权(use_count()>1),没有副作用。

  • 否则,如果*this拥有一个对象p和一个删除器d,则调用d(p)。

  • 否则,*this拥有一个指针p,并调用delete p。

这种行为可以很好地概括为"零规则"。

No。这是定义良好的,并且据我所知没有编译器错误。