2013-10-25 127 views
6

在不使用new的情况下创建std::shared_ptr后可以使用自定义删除程序吗?std :: shared_ptrs的自定义删除程序

我的问题是对象创建是由工厂类及其构造函数处理的&析构函数受保护,这给出了编译错误,我不想使用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<>以及定制删除的好处?这是否意味着必须编写一个分配器?

+1

你可以添加一些(伪)代码来解释你需要什么或其他详细说明吗? (我怀疑是一个XY问题) –

+0

我不明白你的问题,ofc你可以自由地初始化你的值的shared_ptrs,它不一定是由新的操作符返回的东西 –

+0

可能的重复[使用自定义删除与std :: shared \ _ptr](http://stackoverflow.com/questions/12340810/using-custom-deleter-with-stdshared-ptr) –

回答

4

你必须使用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 
+0

谢谢。你能扩展为什么第二个比第一个好吗?我不明白为什么只有第一个泄漏才有可能发生泄漏。 –

+2

在第二种情况下,每次调用'make_X'都会确保从'new'返回的每个指针都立即存储在'std :: shared_ptr'中,所以即使出现异常,也会有一个'shared_ptr',它将删除从'new'返回的实例。 –

+0

有什么合理的吗?这将和make_shared一样,并且可以与非公共的析构函数一起工作?恕我直言,要求公共析构失败的共同指针的全部目的。 – zzz777

7

没有,没有的std::make_shared形式,需要一个定制删除。

如果您需要使用自定义删除程序返回shared_ptr,那么您必须采取性能优化。

想一想:如果你使用make_shared那么它会分配一个更大的内存区域,它可以将引用计数和对象一起存储,并且新的位置将被调用。从make_shared返回的shared_ptr已经有一个自定义的删除器,一个明确调用对象的析构函数,然后释放更大的内存块。

相关问题