自动释放资源的通用句柄
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);
但是要提醒一句:你必须用这种方法声明w
afterrsc
。否则 rsc
将在 w
调用 capi_release
之前被销毁。
然而,由于这不是 unique_ptr
的预期用途,我建议简单地编写一个小包装器 class,如我的其他答案所示。
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);
但是要提醒一句:你必须用这种方法声明w
afterrsc
。否则 rsc
将在 w
调用 capi_release
之前被销毁。
然而,由于这不是 unique_ptr
的预期用途,我建议简单地编写一个小包装器 class,如我的其他答案所示。