如何解决C ++管理RAII风格的一系列资源附件
以下是幻想代码,演示了我要解决的问题(请参见评论// PROBLEM -
);基本上,如何确保在执行可能引发的操作后分离一堆资源句柄。
#include <initializer_list>
// from a C-style API
extern int create_thingie(); // returns non-zero resource handle
extern int create_widget(); // returns non-zero resource handle
extern void attach_thingie(int widget_handle,int thingie_handle);
extern void detach_thingie(int widget_handle,int thingie_handle);
extern void delete_thingie(int handle); // deletes a thingie unless still attached
extern void delete_widget(int handle);
// RAII wrapper for thingies
class thingie {
int resource_handle;
public:
thingie() : resource_handle{create_thingie()} {}
thingie(const thingie&)=delete;
thingie& operator=(const thingie&)=delete;
thingie(thingie&& moved_from)
: resource_handle{moved_from.resource_handle}
{
moved_from.resource_handle = 0;
}
thingie& operator=(thingie&&)=delete;
~thingie() { delete_thingie(this->resource_handle); }
inline int get_handle() const
{
return this->resource_handle;
}
};
// RAII wrapper for widgets
// here identical to thingie,but not in my use-case
class widget {
int resource_handle;
public:
widget() : resource_handle{create_widget()} {}
widget(const widget&)=delete;
widget& operator=(const widget&)=delete;
widget(widget&& moved_from)
: resource_handle{moved_from.resource_handle}
{
moved_from.resource_handle = 0;
}
widget& operator=(widget&&)=delete;
~widget() { delete_widget(this->resource_handle); }
inline int get_handle() const
{
return this->resource_handle;
}
};
class foo {
widget underlying_widget;
public:
foo(std::initializer_list<thingie> thingies);
inline int get_underlying_handle() const
{
return this->underlying_widget.get_handle();
}
};
foo::foo(std::initializer_list<thingie> thingies)
{
for (thingie const& t : thingies)
attach_thingie(this->get_underlying_handle(),t.get_handle());
// do some potentially throwing things
// PROBLEM - thingies might not get detached,causing resource leak
for (thingie const& t : thingies)
detach_thingie(this->get_underlying_handle(),t.get_handle());
}
int main()
{
foo f1{thingie{},thingie{}};
return 0;
}
我的第一个想法是在foo::foo
中创建一个本地类来表示一个附件(或附件数组),该附件在其构造函数中调用attach_thingie
,在其析构函数中调用detach_thingie
,但是与仅在foo::foo
之外的所有路由中运行分离的for循环(即使用try
/ catch (...)
)相比,我不确定如何以零开销的方式进行操作
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。