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
" 即使 p
是 nullptr_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。
我定义并分配了 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
" 即使 p
是 nullptr_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。