在 C + + 中,空的 std: : share_ptr 和空的 std: : share_ptr 有什么区别?

Cplusplus.com shared_ptr页面空荡荡的 std::shared_ptr无效 shared_ptr之间进行区分。Cppreference.com没有明确地指出区别,但是在其对 std::shared_ptr行为的描述中使用了“空”和与 nullptr的比较。

shared_ptr和空 shared_ptr之间有什么区别吗?这种混合行为指针有什么用例吗?非空的空 shared_ptr有意义吗?在正常使用中(例如,如果没有显式地构造一个) ,是否会出现 shared_ptr为空但非空的情况?

如果您使用的是 Boost 版本而不是 C + + 11版本,那么这些答案是否会发生变化?

21391 次浏览

这是 shared_ptr行为的一个奇怪的角落。它有一个构造函数,允许你创建一个 shared_ptr拥有或者 指向或者 指向:

template< class Y >
shared_ptr( const shared_ptr<Y>& r, T *ptr );

使用这个构造函数 股份拥有权r构造的 shared_ptr,但是不管 ptr指向哪个 指向(即,调用 get()operator->()将返回 ptr)。这对于 ptr指向 r拥有的对象的子对象(例如,数据成员)的情况非常方便。

您链接的页面调用一个不拥有任何 空荡荡的shared_ptr和一个指向任何(即其 get() == nullptr) 无效shared_ptr。(标准在这个意义上使用的是 空的,而不是 无效。)您可以构造一个空但不是空的 shared_ptr,但是它不会非常有用。一个空但不为空的 shared_ptr实际上是一个非所有指针,它可以用来做一些奇怪的事情,比如 shared_ptr1(但是我建议先把 shared_ptr放到 API 中的人打一拳)。

boost::shared_ptr也是 有这个构造函数,他们称之为 别名构造函数别名构造函数

空的和空的 share _ ptr 之间有区别吗?

shared_ptr没有控制块,其使用计数被认为是0。空 shared_ptr的副本是另一个空 shared_ptr。它们都是独立的 shared_ptr,不共享公共控制块,因为它们没有公共控制块。空的 abc0可以用缺省构造函数构造,也可以用接受 abc5的构造函数构造。

非空空 shared_ptr具有可与其他 shared_ptr共享的控制块。非空空 shared_ptr的副本是与原 shared_ptr共享相同控制块的 shared_ptr,因此使用计数不为0。可以说,所有的 ABC0拷贝都共享相同的 nullptr.非空空 shared_ptr可以用对象类型的空指针(而不是 nullptr)构造

下面是一个例子:

#include <iostream>
#include <memory>


int main()
{
std::cout << "std::shared_ptr<int> ptr1:" << std::endl;
{
std::shared_ptr<int> ptr1;
std::cout << "\tuse count before copying ptr: " << ptr1.use_count() << std::endl;
std::shared_ptr<int> ptr2 = ptr1;
std::cout << "\tuse count  after copying ptr: " << ptr1.use_count() << std::endl;
std::cout << "\tptr1 is " << (ptr1 ? "not null" : "null") << std::endl;
}
std::cout << std::endl;


std::cout << "std::shared_ptr<int> ptr1(nullptr):" << std::endl;
{
std::shared_ptr<int> ptr1(nullptr);
std::cout << "\tuse count before copying ptr: " << ptr1.use_count() << std::endl;
std::shared_ptr<int> ptr2 = ptr1;
std::cout << "\tuse count  after copying ptr: " << ptr1.use_count() << std::endl;
std::cout << "\tptr1 is " << (ptr1 ? "not null" : "null") << std::endl;
}
std::cout << std::endl;


std::cout << "std::shared_ptr<int> ptr1(static_cast<int*>(nullptr))" << std::endl;
{
std::shared_ptr<int> ptr1(static_cast<int*>(nullptr));
std::cout << "\tuse count before copying ptr: " << ptr1.use_count() << std::endl;
std::shared_ptr<int> ptr2 = ptr1;
std::cout << "\tuse count  after copying ptr: " << ptr1.use_count() << std::endl;
std::cout << "\tptr1 is " << (ptr1 ? "not null" : "null") << std::endl;
}
std::cout << std::endl;


return 0;
}

产出:

std::shared_ptr<int> ptr1:
use count before copying ptr: 0
use count  after copying ptr: 0
ptr1 is null


std::shared_ptr<int> ptr1(nullptr):
use count before copying ptr: 0
use count  after copying ptr: 0
ptr1 is null


std::shared_ptr<int> ptr1(static_cast<int*>(nullptr))
use count before copying ptr: 1
use count  after copying ptr: 2
ptr1 is null

Http://coliru.stacked-crooked.com/a/54f59730905ed2ff