我如何使用一个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
作为一个类的成员?
假设create
和destroy
是自由函数(这似乎是来自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);});