能否同时为std::shared_ptr使用自定义分配器和自定义删除器?在我看来似乎不可能,因为std::allocate_shared没有接受删除器的方式。而且,删除器的唯一合理签名应该是类似于void deleter(T*, const Alloc&)而不仅仅是void deleter(T*)。
有没有办法绕过这个限制?
有没有办法绕过这个限制?
是的,你可以这样做,但一定要明白发生了什么。deleter的目的是销毁对象。allocator用于内部记账结构。
std::shared_ptr<T> sp(new T(args...), std::default_delete<T>(), myalloc);
make_shared
和allocate_shared
的优点在于它们会代替你构建对象,因此你不需要指定一个删除器。它们使用适合其获取资源方式(即通过operator new
和提供的分配器)的自己的删除器。
当然,你也可以创建自己的分配器删除器(例如这个或这里提出的),将其传递给上述构造函数,以配合使用由分配器分配的对象,并使用分配器(或其他不同的分配器!)进行簿记。
在存在长期弱指针或二进制大小重要的情况下,不使用make_shared
/allocate_shared
也是有道理的。
shared_ptr
的构造函数都可以接受它们。allocate_shared
来实现这一点。原因在于,分配器用于分配/释放共享内存。删除器用于销毁正在被管理的对象并释放其内存。allocate_shared
在与共享内存本身相同的存储空间中分配要管理的对象,因此两个操作不再需要分开。因此,您必须使用同一个对象来执行两个过程。分配器用于分配和释放单个分配,并且负责创建和销毁T
。