C++ shared_ptr use_count for nullptr

C++ shared+ptr use_count for nullptr

我定义并分配了 2 个 shared_ptr nullptr。在案例 1 中,我使用了默认构造函数,在案例 2 中,我使用了带有 delete 方法的构造函数。

shared_ptr<int> sptr2(nullptr);

cout << "sptr2 use_count: " << sptr2.use_count() << endl;

shared_ptr<int> sptr6(nullptr, default_delete<int>());

cout << "sptr6 use_count: " << sptr6.use_count() << endl;

输出为:

sptr2 use_count: 0
sptr6 use_count: 1

我不明白为什么 sptr6 在没有任何有效指针的情况下使用计数为 1。

g++ (GCC) 4.8.5 20150623(红帽 4.8.5-16)

根据 C++11 和 C++14 中的 [util.smartptr.shared.const](我没有检查 C++17),如果不传递任何参数,shared_ptr 就是 "empty" .否则,shared_ptr "owns p" 即使 pnullptr_t.

当提供删除器时,这是有道理的(毕竟你必须将删除器存储在某个地方),但是我不能说 single-argument 构造函数的目的是什么。

显然我并不孤单,因为实际函数的 C++11/C++14 规范 ([util.smartptr.shared]/1) 列出了 constexpr shared_ptr(nullptr_t) : shared_ptr() { },这表明了这种构造(但不是提供删除器的构造)应该导致 "empty" shared_ptr!

但这与列出的语义直接矛盾(对于您的两个示例,它专门将 use_count == 1 作为 post-condition),因此看起来是标准中的错误。

GCC 显然选择支持函数规范(cppreference.com)。在这种情况下,至少你的删除器应该是 no-op。

实际使用默认构造函数,这样写:

shared_ptr<int> sptr;

shared_ptr 设计导致不同行为的原因。 SharedPtr引用"control object",控制对象引用"user object".

如果用 nullptr (sptr2) 初始化 shared_ptr,则不会创建控制对象。构造函数什么都不做。

如果您使用删除器 (sptr6) 初始化 shared_ptr,则会创建控制对象来存储删除器。因此,如果创建了控制对象,它的引用计数必须为 1。