C++ 用于恢复以前值的RAII对象 也许我正在考虑这个问题,但是考虑下面的例子: bool some_state = false; // ... later ... some_state = true; do_something(); some_state = false;
现在想象一下,C++ 用于恢复以前值的RAII对象 也许我正在考虑这个问题,但是考虑下面的例子: bool some_state = false; // ... later ... some_state = true; do_something(); some_state = false;,c++,boost,c++03,C++,Boost,C++03,现在想象一下,do\u something()可以抛出。我们不会将某些状态设置回false。最好是有某种自动堆栈,根据记忆以前值的范围推送/弹出: { scoped_restore res( some_state, true ); // This sets some_state to true and remembers previous value (false) do_something(); } // At this point, res is destroyed and
do\u something()
可以抛出。我们不会将某些状态设置回false
。最好是有某种自动堆栈,根据记忆以前值的范围推送/弹出:
{
scoped_restore res( some_state, true ); // This sets some_state to true and remembers previous value (false)
do_something();
} // At this point, res is destroyed and sets some_state back to false (previous value)
boost有这样的东西吗?当然,我可以写我自己的东西,但我想确保我没有首先重新发明轮子。我在MSVC上使用C++ 03,所以我不能使用任何新奇的新C++ 11:(< /P> < p>你正在调用正确的树。Bjarne Stroustrup强烈建议RAII进行异常处理,而不是尝试/捕获/最后。在最新版本的C++编程语言(第四版)中。,他在第13章“异常处理”中完整地概述了他推荐的方法
替换一整章是相当困难的,因此首先,我建议只阅读这一章。然而,基本思想是使用组合,让构造函数保护资源
因此,如果类A保护3个资源,每个资源可能会抛出(可能是一些内存),那么您可以让子对象在其构造函数(而不是A的构造函数)中保护每个资源。关键是,如果允许构造函数完成,那么它是有保证的(通过语言)将调用析构函数。因此,在顶级构造函数中,按如下方式初始化子对象:
class B{
public:
B( int n )
{
//allocate memory (may throw)
}
void *secured_memory;
~B(){
//release memory
}
}
class A{
public:
A( int n )
:b{n}, c{n}, d{n}
{
//will not complete if B, C or D throws
//but because the constructors of B and C completed
//their destructors will be invoked if D throws
}
B b;
C c;
D d;
}
假设存在类C和类D,它们的结构类似于B。因此,在上面的示例中,一些_状态将通过类B、C或D进行保护
这里还有一个关键点。您应该在每个子对象的类中只保护一个资源。这样,可以获取资源并允许构造函数退出(从而确保调用析构函数,从而安全释放资源)或抛出(因此,不获取资源).Boost确实有类似的功能。它被称为state\u saver。它有点隐藏在序列化库中,但它是有文档记录的,而且显然是官方的(即不在某些详细名称空间中)
演示:更多的是编码风格问题,而不是语言本身。只需使用try/catch
。@billz try/catch用于异常处理,这不是正常的预期逻辑。抛出也会影响性能。这不是一个可接受的解决方案。RAII不是编码风格首选项,它是一种设计模式。有,但我不确定用法:BOOST\u SCOPE\u EXIT(some\u state=true);
是的,OP只是想要一个scopeguard,而ScopeExit似乎是一个scopeguard。@Robert Dailey 1.37已经5岁了。。。