7

Is it possible to use a custom deleter after creating a std::shared_ptr without using new?

My problem is that object creation is handled by a factory class and its constructors & destructors are protected, which gives a compile error, and I don't want to use new because of its drawbacks.

To elaborate: I prefer to create shared pointers like this, which doesn't let you set a custom deleter (I think):

auto sp1 = make_shared<Song>(L"The Beatles", L"Im Happy Just to Dance With You");

Or I can create them like this, which does let met set a deleter through an argument:

auto sp2(new Song, MyDeleterFunc);

But the second one uses new, which AFAIK isn't as efficient as the top sort of allocation.

Maybe this is clearer: is it possible to get the benefits of make_shared<> as well as a custom deleter? Would that mean having to write an allocator?

4

2 回答 2

8

不,没有任何形式的std::make_shared需要自定义删除器。

如果您需要使用自定义删除器返回 a shared_ptr,那么您将不得不承受性能损失。

想一想:如果你使用make_sharedthen 它将分配一个更大的内存区域,可以将引用计数和你的对象存储在一起,并且会调用放置 new。shared_ptr返回的 from已经make_shared有一个自定义删除器,它显式调用对象的析构函数,然后释放较大的内存块。

于 2013-10-25T21:47:51.660 回答
4

您必须new在您的情况下使用,std::make_shared以避免额外分配的设计只有在std::make_shared可以使用它自己的(内部)自定义删除器来释放对象和shared_count.

您必须接受使用自己的自定义删除器无法优化分配,但出于安全使用的原因,您仍应使用std::make_shared-like 包装器来封装。new这有助于在对象的构造函数抛出异常并且有人使用的情况下避免内存泄漏

template<typename T>
void f(const T&, const T&);

f( std::shared_ptr<X>(new X), std::shared_ptr<X>(new X) ); // possible leak

代替

std::shared_ptr<X> make_X() { return std::shared_ptr<X>(new X); }
f( make_X(), make_X() ); // no leak
于 2013-10-25T21:45:56.650 回答