cav*_*gru 39 c++ smart-pointers shared-ptr make-shared c++11
从C++ 11开始,由于几个原因,开发人员倾向于将智能指针类用于动态生命周期对象.而对于那些新的智能指针类,标准,甚至建议不使用运营商,new而是建议使用make_shared或make_unique避免一些容易出错.
如果我们喜欢使用智能指针类shared_ptr,我们可以构建一个类似的,
shared_ptr<int> p(new int(12));
Run Code Online (Sandbox Code Playgroud)
我们还希望将自定义删除器传递给智能指针类,
shared_ptr<int> p(new int(12), deleter);
Run Code Online (Sandbox Code Playgroud)
另一方面,如果我们喜欢使用make_shared分配,例如.int,而不是使用new和shared_ptr构造函数,就像上面的第一个表达式,我们可以使用
auto ip = make_shared<int>(12);
Run Code Online (Sandbox Code Playgroud)
但是,如果我们也希望将自定义删除器传递给make_shared,那么有没有正确的方法呢?好像编译器,至少gcc,给出错误,
auto ip = make_shared<int>(12, deleter);
Run Code Online (Sandbox Code Playgroud)
Nic*_*las 52
正如其他人所说,make_shared不能与自定义删除器一起使用.但我想解释原因.
存在自定义删除器是因为您以某种特殊方式分配了指针,因此您需要能够以相应的特殊方式释放它.好吧,make_shared分配指针new.分配的对象new应该被释放delete.标准删除者尽职尽责.
简而言之,如果您可以使用默认的分配行为,那么您也可以使用默认的释放行为.如果您不能使用默认分配行为,则应使用allocate_shared,它使用提供的分配器来分配和取消分配存储.
此外,make_shared允许(并且几乎肯定会)T在同一分配中为shared_ptr 分配内存和控制块.这是你的删除者无法真正了解或处理的事情.鉴于allocate_shared您提供的分配器可以执行分配和解除分配任务,因此能够处理它.
sky*_*ack 11
从文档中,make_shared接受一个参数列表,用于构造T的实例.
此外,文件说:
此函数通常用于从调用new返回的原始指针替换共享指针的构造std :: shared_ptr(new T(args ...)).
因此,您可以推断出无法设置自定义删除器.
要做到这一点,你必须shared_ptr通过正确的构造函数为自己创建.
作为建议列表中构造函数的示例,您可以使用:
template< class Y, class Deleter >
shared_ptr( Y* ptr, Deleter d );
Run Code Online (Sandbox Code Playgroud)
因此,代码将是这样的:
auto ptr = std::shared_ptr(new MyClass{arg1, arg2}, myDeleter);
Run Code Online (Sandbox Code Playgroud)
代替:
auto ptr = std::make_shared<MyClass>(arg1, arg2);
Run Code Online (Sandbox Code Playgroud)
未指定如何make_shared获取对象的内存(它可以使用operator new或malloc或某种分配器),因此自定义删除器无法知道如何做正确的事情。make_shared创建对象,因此您还必须依赖它来正确销毁对象并进行适当的清理,无论是什么。
我们还想将自定义删除器传递给智能指针类,
shared_ptr<int> p(new int(12), deleter);
我认为这不是一个非常现实的例子。当以某种特殊方式获取资源时,通常会使用自定义删除器。如果您只是new像这样创建了它,那么为什么还需要自定义删除器呢?
如果您只想在销毁时运行一些代码,请将其放入析构函数中!这样你仍然可以使用它,make_shared例如
struct RunSomethingOnDestruction {
RunSomethingOnDestruction(int n) : i(n) { }
~RunSomethingOnDestruction() { /* something */ }
int i;
};
auto px = std::make_shared<RunSomethingOnDestruction>(12);
std:shared_ptr<int> p(px, px->i);
Run Code Online (Sandbox Code Playgroud)
这为您提供了一个shared_ptr<int>由make_shared(因此您可以通过 完成内存优化make_shared)创建的 ,它将在销毁时运行一些自定义代码。