我如何使用一个std :: unique_ptr成员的定制删除器?

我有一个unique_ptr成员的类。

class Foo { private: std::unique_ptr<Bar> bar; ... }; 

Bar是一个具有create()函数和destroy()函数的第三方类。

如果我想在独立函数中使用std::unique_ptr ,我可以这样做:

 void foo() { std::unique_ptr<Bar, void(*)(Bar*)> bar(create(), [](Bar* b){ destroy(b); }); ... } 

有没有办法做到这一点与std::unique_ptr作为一个类的成员?

假设createdestroy是自由函数(这似乎是来自OP的代码片段的情况)具有以下签名:

 Bar* create(); void destroy(Bar*); 

你可以这样写你的Foo

 class Foo { std::unique_ptr<Bar, void(*)(Bar*)> ptr_; // ... public: Foo() : ptr_(create(), destroy) { /* ... */ } // ... }; 

请注意,您不需要在此处编写任何lambda或定制删除程序,因为destroy已经是删除程序。

可以在C ++ 11中使用lambda干净地完成(在G ++ 4.8.2中testing)。

鉴于这个可重用的typedef

 template<typename T> using deleted_unique_ptr = std::unique_ptr<T,std::function<void(T*)>>; 

你可以写:

 deleted_unique_ptr<Foo> foo(new Foo(), [](Foo* f) { customdeleter(f); }); 

例如,用FILE*

 deleted_unique_ptr<FILE> file( fopen("file.txt", "r"), [](FILE* f) { fclose(f); }); 

有了这个,您可以使用RAII获得exception安全清除的好处,而无需尝试/捕捉噪音。

你只需要创build一个删除类:

 struct BarDeleter { void operator()(Bar* b) { destroy(b); } }; 

并将其作为unique_ptr的模板参数提供。 您仍然需要在构造函数中初始化unique_ptr:

 class Foo { public: Foo() : bar(create()), ... { ... } private: std::unique_ptr<Bar, BarDeleter> bar; ... }; 

据我所知,所有stream行的c ++库都正确地实现了这一点; 因为BarDeleter实际上没有任何状态,所以不需要在unique_ptr占用任何空间。

你可以简单地使用你的销毁函数std::bind

 std::unique_ptr<Bar, std::function<void(Bar*)>> bar(create(), std::bind(&destroy, std::placeholders::_1)); 

但是当然你也可以使用lambda。

 std::unique_ptr<Bar, std::function<void(Bar*)>> ptr(create(), [](Bar* b){ destroy(b);});