我正在使用很少的库函数来返回使用malloc或new创建的指针。 因此,我根据使用的分配类型拥有自己的客户解除分配器。
E.g
shared_ptr<int> ptr1(LibFunctA(), &MallocDeleter); //LibFunctA returns pointer created using malloc
shared_ptr<int> ptr2(LibFunctB(), &newDeleter); //LibFunctB returns pointer created using new
现在,我理解这是对上面的deallocator的一种非常天真的用法,但是它还有很多其他场景?
另外,如何使用客户分配器?我尝试分配如下的自定义分配器,但现在我如何实际调用它?这种功能在哪里有帮助?
shared_ptr<int> ptr3(nullptr_t, &CustomDeleter, &CustomAllocator); //assume both functs are defined somewhere.
答案 0 :(得分:6)
我没有看到任何关于以这种方式使用删除的“天真”。毕竟这是这个功能的主要目的;销毁未使用标准C ++方法分配的指针对象。
分配器适用于需要控制如何分配和删除shared_ptr
的内存控制块的情况。例如,您可能有一个内存池,您希望这些内容来自,或者如果您处于内存有限的情况下,通过new
分配内存是不可接受的。由于控制块的类型最多为shared_ptr
,因此除了使用某种分配器之外,没有其他方法可以控制它的分配方式。
答案 1 :(得分:3)
shared_ptr
的自定义删除器对于包装一些(通常)C资源非常有用,以后需要调用一个释放函数。例如,您可能会执行以下操作:
shared_ptr<void> file(::CreateFileW(...), ::CloseHandle);
这样的例子在C库中比比皆是。这节省了以后必须手动释放资源并处理可能的异常和其他恶意行为。
答案 2 :(得分:1)
我认为自定义分配器将用于为“共享计数”对象分配空间,该对象存储deallocator(删除器)和引用计数器的副本。
关于自定义删除器可以用于什么......
已经提到过一种用法:make shared_ptr
与必须由某些特殊函数删除的对象兼容(如FILE
删除fclose
),而不必将其包含在内一个辅助类,负责正确的删除。
自定义删除器的另一个用途是池。该池可以分发用“特殊”删除器初始化的shared_ptr<T>
,它不会真正删除任何内容,而是将对象返回到池中。
还有一件事:删除器已经是实现某些shared_ptr
功能所必需的。例如。删除的类型始终在创建时固定,并且与正在初始化的shared_ptr
的类型无关。
您可以使用shared_ptr<Base>
实际初始化Derived
来创建shared_ptr
。 Derived
保证在删除对象时,即使Base
没有虚拟dtor,它也会被shared_ptr
删除。为了实现这一点,{{1}}已经必须存储有关如何删除对象的一些信息。因此,允许用户指定一个完全自定义的删除器不会花费任何成本(就运行时性能而言),也不需要额外的代码。
可能有很多其他场景可以很好地利用自定义删除器,这就是我到目前为止所提出的。