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

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

说我有一个class喜欢

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

我必须要有像

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

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

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

不是,那是智能指针的要点:自动管理内存

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

如果您不提供析构函数,将生成一个默认析构函数:

§ 12.4.4 If a class has no user-declared destructor, a destructor is implicitly declared as defaulted

销毁你的class将保证销毁成员。

§ 12.4.8 After executing the body of the destructor and destroying any automatic objects allocated within the body, a destructor for class X calls the destructors for X's direct non-variant non-static data members(...)

shared_ptr 的意思是:

§ 20.8.2.2.2.1

~shared_ptr();

Effects:

  • If *this is empty or shares ownership with another shared_ptr instance (use_count() > 1), there are no side effects.

  • Otherwise, if *this owns an object p and a deleter d, d(p) is called.

  • Otherwise, *this owns a pointer p, and delete p is called.

此行为很好地概括为 The Rule Of Zero

没有。这是明确定义的,没有我所知道的编译器错误。

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