RAII对象,用于恢复以前的值
RAII object for restoring previous value
也许我想得太多了,但请考虑以下示例:
bool some_state = false;
// ... later ...
some_state = true;
do_something();
some_state = false;
现在假设do_something()
可以投掷。我们不会将some_state
设置回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:(
Boost确实有类似的东西。它被称为state_saver。它有点埋在序列化库中,但它是有文档记录的,而且显然是官方的(即不在一些详细的命名空间中)。
http://www.boost.org/doc/libs/1_56_0/libs/serialization/doc/state_saver.html
演示:http://rextester.com/NVXUG70771
你说得对。Bjarne Stroustrup强烈建议将RAII用于异常处理,而不是try/catch/finally。在最新版的《C++程序设计语言》(第4版)中,他在第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。因此,在上面的例子中,some_state将通过类B、C或D来保护。
这里还有一个关键点。应该只保护每个子对象类中的单个资源。这样,资源被获取,构造函数被允许退出(从而确保析构函数被调用,从而安全地释放资源)或抛出(因此,不获取资源)。
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 将对象移动到std::shared_ptr
- 代理对象的常量正确性
- 提升 ASIO 无法识别计时器对象
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 如何返回一个类的两个对象相加的结果
- 使用std::函数映射对象方法
- 如何将一个字节数组正确地恢复为C 中的对象
- RAII对象,用于恢复以前的值
- 当我调用方法c++时,对象正在恢复为Null
- C++RAII来管理对象状态的更改和恢复
- C++:在回调中恢复对象指针(API 不支持user_data指针)