C ++中的空和空std :: shared_ptr有什么区别?

时间:2014-09-18 19:16:55

标签: c++ c++11 shared-ptr

cplusplus.com shared_ptr page区分 std::shared_ptr null shared_ptrcppreference.com page并没有明确地区分出来,但是同时使用"空"并在nullptr行为的描述中与std::shared_ptr进行比较。

shared_ptr之间有区别吗?这种混合行为指针有用例吗?非空null shared_ptr是否有意义?在正常使用中是否会出现这种情况(即如果你没有明确构造一个),你最终会得到一个空的但非空的shared_ptr

如果您使用的是Boost版本而不是C ++ 11版本,那么这些答案中的任何一个都会改变吗?

2 个答案:

答案 0 :(得分:76)

这是shared_ptr行为的一个奇怪角落。它有一个构造函数,允许您创建拥有某事物的shared_ptr指向其他内容:

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

使用此构造函数构建的shared_ptrr共享所有权,但指向无论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_ptrhas 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;
}

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