我对以下代码段感到困惑
#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)
答案 0 :(得分:3)
这里的问题实际上与共享指针无关,您只是误解了一些自己的代码。该行:
shared_ptr<int> (q);
不是 使用shared_ptr<int>
作为构造函数参数的匿名q
的构造。它实际上是一个名为 shared_ptr<int>
的声明。您确实写过:
shared_ptr<int> q;
显然不会编译,因为您已经在同一块中使用了名称q
。注释掉的代码 将被编译,因为它是一个不同的块,而内部q
将shadow外部q
。
也:
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
时,您仅对在线程之间传递的对象使用原子计数器,而对其余对象使用普通的整数计数器。