我遇到了this帖子和@kerek SB声明的其中一个答案
std::shared_ptr<Object> p1 = std::make_shared<Object>("foo"); std::shared_ptr<Object> p2(new Object("foo"));
在你的代码中,第二个变量只是一个裸指针,而不是一个 共享指针。
现在开始了。 make_shared(实际上)更有效率,因为 它将参考控制块与实际值一起分配 一个动态分配中的对象。相比之下,构造函数 对于采用裸对象指针的shared_ptr必须分配另一个 引用计数的动态变量。权衡是这样的 make_shared(或其堂兄allocate_shared)不允许你这样做 指定自定义删除器,因为分配是由 分配器。
(这不会影响对象本身的构造。来自 对象的观点是两个版本之间没有区别。 共享指针本身的效率更高,而不是托管 对象。)
现在我对这篇文章有两个问题,如果有人能澄清这个帖子,我会很感激。
为什么第二个不是共享指针?这不会增加引用计数
make_shared如何只进行一次内存分配,而new则为2 让make_shared更有效率?
对此的一点澄清将不胜感激。
答案 0 :(得分:7)
在那个问题中,“第二个变量”引用了这一行:
auto ptr_res2(new Object("new")); // this creates an Object*
不是这一个:
std::shared_ptr<Object> p2(new Object("foo")); // this creates a shared_ptr<Object>
为什么make_shared
在一次分配时效率更高的最佳解释是比较图像。以下是std_shared_ptr<Object>(new Object)
的样子:
shared_ptr
有Widget*
,但它与ref计数器不在同一个内存块中,因为它们是分开分配的。传入了Widget*
,并且内部分配了引用计数块,这就是Widget
位于单独的内存空间中的原因。
另一方面,这是一个分配的样子:
(我偷了Herb Sutter的两张照片)。我们仍然需要一个Widget
和一个引用计数块,但是只需要一次调用new
/ malloc
就可以获取整个内存块,只需要足够大,所以{{1并且ref计数块在内存中最终连续。
答案 1 :(得分:3)
被称为第二个变量的代码实际上就是这个(取自OP代码):
auto ptr_res2(new Object("new"));
这不创建std::shared_ptr
,它会创建指向Object
的指针。
使用带有裸指针的构造函数创建std::shared_ptr
时,必须将指针传递给已分配的内存(例如,使用new
分配)。这意味着在创建std::shared_ptr
对象本身时已经分配了对象的内存。 std::shared_ptr
需要为自己的工作分配内存,例如参考柜台。因此,有2个分配:使用new
传递给std::shared_ptr
的ctor的分配和构建std::shared_ptr
本身时需要的分配。
Object* ptr = new Object{"Foo"}; // Allocation 1 (object).
std::shared_ptr<Object> p1{ptr}; // Allocation 2 (internal counters).
帮助函数std::make_shared
只使用1个分配,因为你传递构建对象,不是所需的参数指向对象本身的指针。然后,std::make_shared
可以在保存对象和ref计数器时分配内存。
auto p2 = std::make_shared<Object>{"Foo"} // Allocation 1 (object & counter).
答案 2 :(得分:2)
为什么第二个不是共享指针?这不会增加引用计数
我相信引用是指原始海报的代码,它声称创建了一个智能指针,但实际上并没有这样做。 ptr_res2
只是一个常规指针。
cout << "Create smart_ptr using new..." << endl;
auto ptr_res2(new Object("new"));
cout << "Create smart_ptr using new: done." << endl;
make_shared如何只进行一次内存分配,而new将两次内存分配,从而使make_shared更有效率
make_shared
需要为计数器和对象本身分配一个槽。可以一次性分配内存,然后将其中一部分用于计数器,其余部分用于对象。
请注意,这也意味着计数器和对象本身在内存中彼此相邻,从而改善了数据的局部性。
答案 3 :(得分:1)
http://www.cplusplus.com/reference/memory/shared_ptr/shared_ptr/