问题描述
以下是幻想代码,演示了我要解决的问题(请参见评论// 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 (将#修改为@)