我们假设我有一个名为Derived
的类,它继承自一个名为Base
的类。 Base
很特别 - 虽然它可能是使用new创建的,但它必须通过自定义删除器进行破坏。
我希望Base
中的unique_ptr
以及名为BaseDeleter
的自定义删除工具。这也允许我拥有从Base
派生的其他类。出于例外安全性和一致性的考虑,我希望使用std::make_unique
来协助我的unique_ptr
。
我创建了一个小片段,演示了我想要的内容:
#include <memory>
class Base
{
};
class Derived : public Base
{
};
struct BaseDeleter
{
void operator()(Base* base)
{
// Perform some special deleting
}
};
class Big
{
public:
Big()
{
//pointer.reset(new Derived()); // This works!
pointer = std::make_unique<Derived, BaseDeleter>(); // But this doesn't...
}
private:
std::unique_ptr<Base, BaseDeleter> pointer;
};
int main()
{
Big clazz;
}
不幸的是,无法在Visual Studio 2015 Update 2和gcc-5.1上进行编译。 (ideone)
为什么这不起作用?如何使用std::make_unique
分配此类std::unique_ptr
?
答案 0 :(得分:2)
Make unique不适用于自定义删除器。自己写或不使用它。
这与你的问题中的基础/派生并发症无关,这是一个红色的鲱鱼。
答案 1 :(得分:2)
这是make_unique
的签名之一(我认为你希望使用的签名之一):
template< class T, class... Args >
unique_ptr<T> make_unique( Args&&... args );
其中T
是您要创建的对象的类型,Args...
是您要转发给构造函数的参数类型。
正如您所看到的,您无法使用智能指针的make_*
辅助函数指示自定义删除器(既不是make_unique
也不是make_shared
)。
您必须显式构造指针,如下所示:
std::unique_ptr<T, D> ptr{new T{)};
如果删除器不是默认可构造的,则可以执行以下操作:
std::unique_ptr<T, D> ptr{new T{}, d};
其中d
是删除器的实例。