自动释放资源的通用句柄

Generic handle that auto releases resource

STL 或 boost 中是否有通用句柄 class?我正在与一些具有 alloc、release api 的 C 代码交互。我想使用句柄来自动释放资源。

例如:

some_resource_type rsc;  
int err = capi_alloc(&rsc);
if (err != NOERR) {
   // .. do work with resource

   capi_release(rsc);
}  

我想要类似的东西

// looking for this class
class wrapper { 
public:
     wrapper(T obj, void (del)(T&)):obj(obj_),del_(del) {}
     ~wrapper() {_del(obj);}
     T obj_;
     void (del_)(T&);
};

some_resource_type rsc;  
int err = capi_alloc(&rsc);
wrapper w;
if (err != NOERR) {
    w = wrapper(rsc, &capi_release);
    // .. do work with resource
}  
// then auto release

在 STL 或 boost 中有类似的东西吗?它本质上是一些具有自定义创建和自定义删除的独特指针实现。

P.S。我没有编译包装器代码,它可能无法运行。

你想要的是一个智能指针,这些在最近的 C++ 和几乎所有可满足的 Boost 变体中都有;如果您使用的是 C++11,请将 boost 替换为 std:

  • boost::shared_ptr
  • boost::weak_ptr

由于 std::unique_ptr 仅支持堆分配而不支持自定义分配器,您可以构建自己的基于堆栈的包装器 class:

template<class T, int (& Allocator)(T*), void (& Deallocator)(T*)>
class wrapper {
public:
    wrapper() : err_(Allocator(&obj_)) {}
    ~wrapper() { if (err_ != NOERR) Deallocator(&obj_); }
    T& obj() { return obj_; }
    int err() { return err_; }
private:
    T obj_;
    int err_;
};

并像这样使用它:

wrapper<some_resource_type, capi_alloc, capi_release> rsc;  // capi_alloc called
if (rsc.err() != NOERR) {
    // .. do work with rsc.obj()
}
// capi_release called when rsc goes out of scope (if err_ != NOERR)

如果你在编译时不知道allocator和deallocator函数是什么,那就把它们传递给构造函数并存储为成员数据。

您实际上可以(ab)使用 std::unique_ptr 及其第二个模板参数(自定义释放器):

std::unique_ptr<some_resource_type, void (&)(some_resource_type*)> w(nullptr, &capi_release);

然后在你的 if:

w.reset(&rsc);

但是要提醒一句:你必须用这种方法声明wafterrsc。否则 rsc 将在 w 调用 capi_release 之前被销毁。

然而,由于这不是 unique_ptr 的预期用途,我建议简单地编写一个小包装器 class,如我的其他答案所示。