我遇到了一个类实例函数,它需要临时更改一个类实例变量,然后在函数完成时恢复它.该函数在整个地方都有返回语句,并且在每次返回之前都有一个恢复语句.这对我来说似乎很混乱,更不用说在抛出异常时会感到害怕.
作为一种改进,我使用内部类定义提出了这种泛化.这是一个示例驱动程序(类恢复程序).
class Unwind { private: bool b_active_; ///< the thing I want to be restored templateclass restorer { T* ref_; T save_; public: restorer(T* perm) : ref_(perm), save_(*ref_) {}; ~restorer() { *ref_ = save_; } }; public: Unwind() : b_active_(false) {}; void a() { out("a in"); b(); out("a end"); } void b() { out("b in"); { restorer trust_in_the_stack(&b_active_); // "restorer" created on the stack b_active_ = true; // change b_active_ only while "within" b() c(); out("b inner end"); } out("b end"); } void c() { out("c in"); d(); out("c end"); } void d() { out("d in"); cout << "deepest" << endl; out("d end"); } void out(const std::string& msg) { std::cout << msg << ": " << b_active_ << std::endl; } }; int main() { Unwind u; u.a(); return 0; }
使用g ++ 4.2.3(-Wall)的输出是:
a in: 0 b in: 0 c in: 1 d in: 1 deepest d end: 1 c end: 1 b inner end: 1 b end: 0 a end: 0
这是我对"b end"的期望.
我觉得在Unwind类中定义类恢复器有助于阻止滥用.
我的问题是,是否有一般和更安全的方法来做到这一点?我担心终身问题.
编辑:请假设没有线程,但堆栈上的"下游"方法会根据此b_active_标志更改行为.
我同意亚当皮尔斯也认为你应该更喜欢指针引用:
templateclass restorer { T& ref_; T save_; public: restorer(T& perm) : ref_(perm), save_(ref_) {}; ~restorer() { ref_ = save_; } };