创建std::shared_ptr后不使用new是否可以使用自定义删除器?

我的问题是对象创建是由工厂类处理的,并且其构造函数和析构函数受到保护,这会产生编译错误,并且由于其缺点,我不想使用new

详细说明:我更喜欢创建这样的共享指针,这不允许您设置自定义删除器(我认为):

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

或者我可以这样创建它们,这确实让我可以通过参数设置删除器:
auto sp2(new Song, MyDeleterFunc);

但是第二个使用new,AFAIK的效率不及顶级分配。

也许这更清楚:是否有可能获得make_shared<>和自定义删除器的好处?这是否意味着必须编写分配器?

最佳答案

在这种情况下,您必须使用new,因为std::make_shared的设计可以避免额外的分配,只有在std::make_shared可以使用其自己的(内部)自定义删除器释放对象和shared_count的组合内存的情况下,该分配才有效。

您必须接受自己的自定义删除器无法优化分配,但是出于安全使用的原因,您仍应使用类似于std::make_shared的包装器来封装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

09-30 12:03