块内get()的共享指针

时间:2019-03-14 20:55:59

标签: c++11

我对以下代码段感到困惑

    #include <iostream>
    #include <memory>

    using namespace std;

    int main()
    {

        int *iptr = new int(12); //create built-in pointer

        shared_ptr<int> s(iptr); //create shared pointer to it

        int *q = s.get();        //get built-in back using get (redundant step, but I was practicing)

        shared_ptr<int> (q); //Does NOT work without giving it a separate block ; error: conflicting declaration ‘std::shared_ptr q’ 

        //{shared_ptr<int> (q);} //This works!!

        return 0;
    }

我的问题是,为什么一个有效而另一个无效?作用域块中的那个叫什么名字?如果我们遵循以下语法[type name(args)

,似乎没有名称

2 个答案:

答案 0 :(得分:3)

这里的问题实际上与共享指针无关,您只是误解了一些自己的代码。该行:

shared_ptr<int> (q);

不是 使用shared_ptr<int>作为构造函数参数的匿名q的构造。它实际上是一个名为 shared_ptr<int>的声明。您确实写过:

shared_ptr<int> q;

显然不会编译,因为您已经在同一块中使用了名称q。注释掉的代码 将被编译,因为它是一个不同的块,而内部qshadow外部q

也:

  • should避免直接使用new。请改用std::make_shared<int>()
  • 从不传递指向具有std::shared_ptr<>的构造函数的另一个所有者的内存的指针,因为该构造函数取得了内存的所有权,并将假定它即使该内存已由原始所有者释放,也可以使用。

答案 1 :(得分:2)

我走上正轨,@ einpoklum正确了。


您不能从同一 plain 指针创建多个shared_ptr。所有其他shared_ptr必须是另一个shared_ptr的副本。

这是因为shared_ptr必须分配另一个对象来维护对象的引用计数器,而 plain 指针的shared_ptr构造函数会这样做。 shared_ptr复制构造函数只是增加该引用计数器。

当您从同一个 plain 指针创建多个shared_ptr时,它们将分配自己的引用计数器,最终导致多次删除您的对象。导致未定义的行为(通常在第二次删除时崩溃)。


还有boost::intrusive_ptr期望引用计数器位于对象内部。因此,可以从同一 plain 指针创建多个boost::intrusive_ptr,因为它们都在对象内部使用了完全相同的引用计数器。

boost::intrusive_ptr也比shared_ptr更有效,但是它不支持弱指针。

boost::intrusive_ptr的效率更高,因为它的大小与普通指针相同(shared_ptr的大小是原来的两倍),因为它不必分配带有引用计数器的单独结构,并且Deleter对象在其他位置,并保留另一个指向该对象的指针。

在多线程应用程序中,shared_ptr始终使用更昂贵的原子增量/减量来维护参考计数器,即使您从未在线程之间传递这些指针也是如此。在设计良好的应用程序中,只有shared_ptr个用于某些T的线程才能通过线程传递,并且只有那些shared_ptr<T>个需要使用原子计数器。使用boost::intrusive_ptr时,您仅对在线程之间传递的对象使用原子计数器,而对其余对象使用普通的整数计数器。