cplusplus.com shared_ptr
page区分空 std::shared_ptr
和 null shared_ptr
。 cppreference.com page并没有明确地区分出来,但是同时使用"空"并在nullptr
行为的描述中与std::shared_ptr
进行比较。
空shared_ptr
之间有区别吗?这种混合行为指针有用例吗?非空null shared_ptr
是否有意义?在正常使用中是否会出现这种情况(即如果你没有明确构造一个),你最终会得到一个空的但非空的shared_ptr
?
如果您使用的是Boost版本而不是C ++ 11版本,那么这些答案中的任何一个都会改变吗?
答案 0 :(得分:76)
这是shared_ptr
行为的一个奇怪角落。它有一个构造函数,允许您创建拥有某事物的shared_ptr
,指向其他内容:
template< class Y >
shared_ptr( const shared_ptr<Y>& r, T *ptr );
使用此构造函数构建的shared_ptr
与r
共享所有权,但指向无论ptr
指向哪个(即,调用get()
或operator->()
将返回ptr
)。对于ptr
指向r
所拥有的对象的子对象(例如,数据成员)的情况,这很方便。
您关联的网页调用shared_ptr
,其中没有任何内容为空,而shared_ptr
则指向任何内容(即get() == nullptr
)空。 (空在这个意义上是由标准使用的; null 不是。)你可以构造一个null-but-not-empty shared_ptr
,但它不会很有用。一个空但非空的shared_ptr
本质上是一个非拥有的指针,它可以用来做一些奇怪的事情,比如passing a pointer to something allocated on the stack to a function expecting a shared_ptr
(但是我建议对任何放shared_ptr
的人进行打击首先在API内部。)
boost::shared_ptr
也has this constructor,他们称之为别名构造函数。
答案 1 :(得分:6)
null和null shared_ptr之间是否有区别?
空shared_ptr
没有控制块,其使用次数被视为0.空shared_ptr
的副本是另一个空的shared_ptr
。它们都是独立的shared_ptr
,它们不共享公共控制块,因为它们没有它。可以使用默认构造函数或使用shared_ptr
的构造函数构造空nullptr
。
非空null shared_ptr
具有可与其他shared_ptr
共享的控制块。非空shared_ptr
的副本是shared_ptr
,它与原始shared_ptr
共享相同的控制块,因此使用计数不为0. 可以说是{{的所有副本1}}共享相同的shared_ptr
。非空null 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;
}