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

R.M*_*.M. 75 c++ shared-ptr c++11

cplusplus.com shared_ptr页面召唤出一个区分 std::shared_ptr shared_ptr.该cppreference.com页面没有明确叫出区别,但同时使用"空",并比较nullptr其描述std::shared_ptr行为.

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

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

T.C*_*.C. 77

这是一个奇怪的shared_ptr行为角落.它有一个构造函数,可以让你做出shared_ptr拥有的东西,别的东西:

template< class Y > 
shared_ptr( const shared_ptr<Y>& r, T *ptr );
Run Code Online (Sandbox Code Playgroud)

shared_ptr使用此构造方法构建股票所有权r,但什么ptr点(即调用get()operator->()返回ptr).这对于ptr指向所拥有的对象的子对象(例如,数据成员)的情况是很方便的r.

你链接的页面调用一个shared_ptr没有空的东西,并且shared_ptr它指向什么都没有(即,哪个get() == nullptr)为null.(在这种意义上,标准使用Empty ; null不是.)您可以构造一个null-but-not-empty shared_ptr,但它不会非常有用.一个空但shared_ptr非空的本质上是一个非拥有的指针,它可以用来做一些奇怪的事情,例如将指针传递给堆栈上分配的东西到一个期望的函数shared_ptr(但是我建议打击任何放在shared_ptr里面的人API首先).

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

  • 值得注意的是:**C++11§20.7.2.2.1(p16)**"注意:这个构造函数允许使用非NULL存储指针创建一个空的`shared_ptr`实例." 另外值得一提的是前面的注释(p15),"为了避免悬空指针的可能性,这个构造函数的用户必须确保`p`至少在`r`的所有权组被销毁之前保持有效." 确实很少使用的建筑. (8认同)
  • null-but-nonety`shared_ptr`s*可以*有用,以确保一旦所有拥有的指针超出范围(即使出现异常!),某些函数也会被执行.不确定,现在是否有特殊课程. (3认同)
  • 别名构造函数源自Bloomberg,并且在Boost实现之前被提议用于该标准(参见[N1851](http://www.open-std.org/jtc1/SC22/wg21/docs/papers/2005/n1851). PDF)).我更喜欢标准的术语"与`r`共享所有权"这句话"拥有'r`拥有的任何东西" (2认同)

ant*_*_rh 6

空和shared_ptr之间有区别吗?

Empty shared_ptr没有控制块,其使用计数被认为是0.复制空shared_ptr是另一个空shared_ptr.它们都是独立shared_ptr的,不共享公共控制块,因为它们没有它.shared_ptr可以使用默认构造函数或使用构造函数构造Empty nullptr.

非空null shared_ptr具有可与其他shared_ptrs 共享的控制块.非空null的副本shared_ptrshared_ptr与原始共享相同的控制块,shared_ptr因此使用计数不为0. 可以说所有副本的shared_ptr共享相同nullptr.shared_ptr可以使用对象类型的空指针构造非空null (不是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;
}
Run Code Online (Sandbox Code Playgroud)

它输出:

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
Run Code Online (Sandbox Code Playgroud)

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