Arv*_*vid 8 c++ shared-ptr make-shared c++11
事后看来,给定的是make_shared,如果shared_ptr用C++ 11引入它,会有一个带有原始指针的构造函数吗?
有没有强大的论据或用例支持这个构造函数?
这本来是可以避免的有据可查的陷阱异常安全和内存分配/性能优势利用make_shared.
我认为需要shared_ptr构建的另一个优点make_shared是它可能是引擎盖下的单个指针,降低了它的内存使用并使atomic_compare_exchange之类的东西变得更简单(并且可能更高效).(请参阅C++中的演示文稿)
编辑
我知道一个shared_ptr基本上是一个intrusive_ptr(对象和控制块合并)会缺少当前std :: shared_ptr所具有的功能.喜欢:
将对象与控制块分开释放的能力(如果你长期生活在weak_ptrs中,这很好)
与提供原始指针的库的兼容性以及释放它们的责任
使用自定义删除程序保留任意资源的能力(或者对于非拥有指针没有删除程序)
能够在保持父对象存活的同时指向子对象(例如成员).
我建议的是,这些功能可能不常用(或者在使用它作为raii-wrapper的情况下)可能不是最合适的,以保证额外的费用:
在C++ 98世界中(引入了shared_ptr),make_shared不太实用且用户友好性较差(缺乏完美的转发需要参考包装器和缺少可变参数模板使得实现笨重).
Bar*_*rry 14
事后看来,给定的是
make_shared,如果shared_ptr用C++ 11引入它,会有一个带有原始指针的构造函数吗?
如果你不控制对象的分配怎么办?如果您需要使用自定义删除器怎么办?如果你需要列表初始化而不是parens怎么办?
这些案件都不是由处理的make_shared.
另外,如果你正在使用weak_ptr,shared_ptr分配的通道make_shared也不会释放任何内存,直到所有weak_ptrs都被销毁.因此,即使你有一个普通的共享指针,上面没有一个适用,你可能仍然喜欢原始指针构造函数.
另一种情况是,如果你的类型为operator new和提供重载operator delete.这些可能使它不适合make_shared,因为那些超载不会被调用 - 并且可能它们存在是有原因的.
Nic*_*las 13
你的逻辑的问题是相信,为什么shared_ptr管理指针和get指针之间的区别是因为make_shared不可用.因此,如果我们强迫每个人都用来make_shared创造shared_ptr,我们就不需要这种区别.
这是不正确的.
你可以实现shared_ptr没有这种区别的基于指针的构造函数.毕竟,在初始创建托管时shared_ptr,get指针和托管指针是相同的.如果你想shared_ptr成为sizeof(T*),你可以从托管块中shared_ptr获取get指针.无论是否T嵌入在托管块中,都是如此.
因此,这种区别实际上没有任何关系,make_shared并且它能够将其嵌入到T与托管块相同的内存中.或者更确切地说,缺乏它.
不,托管指针和之间的区别get是创建的指针,因为它增加功能来shared_ptr.重要的.你列出了其中一些,但你错过了其他人:
具有shared_ptr基类的能力.那是:
shared_ptr<base> p = make_shared<derived>(...);
Run Code Online (Sandbox Code Playgroud)
为此,您必须区分特定实例指向的内容与控制块控制的内容.
static_pointer_cast和dynamic_pointer_cast(以及reinterpret_pointer_cast在C++ 17中).这些都依赖于托管指针和get指针之间的区别.
enable_shared_from_this在基类中.A shared_ptr指向一个类型的成员子对象,该对象本身由a管理shared_ptr.同样,它要求托管指针与get指针不同.
您似乎也忽略了管理不是由您创建的指针的能力.这是一项关键能力,因为它允许您与其他代码库兼容.在内部,您可以shared_ptr用来管理1998年编写的库所做的事情.
按照自己的方式,将代码划分为两个时代:pre-C++ 11和post-C++ 11.shared_ptr对于没有为C++ 11明确编写的代码,您将不做任何事情.
将所有这些功能包装成单一类型的事情是这样的:
你不需要另一个.
shared_ptr,因为它满足了这么多的需求,几乎可以在任何地方有效地使用.它可能不是绝对,最高效型可能,但会做的工作在几乎所有情况下.这样做并不是很慢.
它使用多态来处理共享所有权.它处理成员对象的共享所有权.它处理您未分配的内存的共享所有权.它处理具有特殊分配/释放需求的内存共享所有权.等等.
如果您需要共享所有权语义,并且需要它才能工作,那么shared_ptr每次都会让您回头.根据您提出的建议,总会有一些限制因素可以帮助您完成工作.
默认情况下,优先使用的类型优先于不支持的类型.
std::shared_ptr 不仅仅是在堆上分配对象.
考虑将其用作自动关闭共享文件句柄:
#include <cstdio>
#include <memory>
int main()
{
auto closer = [](FILE* fp) { std::fclose(fp); };
auto fp = std::shared_ptr<FILE>(std::fopen("foo.txt", "r"),
closer);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1788 次 |
| 最近记录: |