Scope variables/guards问询:如何实现scope exit自动finalize的变量与guard
Scope Guard 作用域守卫实现方案
这种需要在作用域进入、退出时自动执行指定函数的组件就是常说的作用域守卫(Scope Guard),完全可以实现,核心依赖编程语言的自动资源回收特性,以下是主流场景的实现方案:
C++ 原生实现(基于RAII特性)
C++中栈对象的析构函数会在对象离开作用域时自动触发,无论作用域是正常返回还是异常抛出都会执行,是最稳妥的实现方式:
基础实现代码
#include <functional> #include <utility> class ScopeGuard { public: // 构造函数传入初始化函数、退出清理函数,构造时立即执行初始化逻辑 template <typename InitFn, typename ExitFn> ScopeGuard(InitFn&& init_fn, ExitFn&& exit_fn) : m_exitFn(std::forward<ExitFn>(exit_fn)) { std::forward<InitFn>(init_fn)(); } // 析构函数自动执行退出清理逻辑 ~ScopeGuard() { if (m_exitFn) m_exitFn(); } // 禁止拷贝、移动,避免生命周期混乱 ScopeGuard(const ScopeGuard&) = delete; ScopeGuard& operator=(const ScopeGuard&) = delete; ScopeGuard(ScopeGuard&&) = delete; ScopeGuard& operator=(ScopeGuard&&) = delete; private: std::function<void()> m_exitFn; };
使用示例
#include <iostream> int main() { std::cout << "进入外层作用域\n"; { // 声明守卫对象,初始化、清理逻辑作为参数传入 ScopeGuard guard( [](){ std::cout << "执行作用域进入时的初始化操作\n"; }, [](){ std::cout << "执行作用域退出时的清理操作\n"; } ); std::cout << "执行作用域内的业务逻辑\n"; // 此处即使抛出异常,清理逻辑依然会被执行 } std::cout << "回到外层作用域\n"; return 0; }
扩展功能
如果需要支持「中途取消清理操作」的需求,只需要在类中新增一个布尔标记位,提供dismiss()方法修改标记,析构时判断标记再决定是否执行清理函数即可。
其他编程语言的同类实现
- Rust:为自定义结构体实现
Droptrait,drop方法会自动在变量离开作用域时调用 - Python:实现
__enter__和__exit__方法构造上下文管理器,配合with语句使用,__exit__方法会在with块结束时自动执行 - Go:直接使用内置的
defer关键字注册延迟执行函数,无需自定义结构体
内容的提问来源于stack exchange,提问作者Hrisip
相关产品推荐
相关产品推荐

