C++作为一门Native Langueages,在C++98/03时代,资源管理是个大问题。而内存管理又是其中最大的问题。申请的堆内存需要手动分配和释放,为了确保内存正确释放,一般原则是"谁分配谁负责释放",但软件工程的复杂性、程序员的编码水平参差不齐等仍然导致内存泄漏、空悬指针等问题。严重的内存泄漏可能很快导致服务器内存耗光而运行崩溃。
托管语言为了解决这种问题引入了GC,把内存管理交给机器处理。而C++解决办法一个是手动重启,一个就是今天的主角RAII。
RAII全称(Resource Acquisition is Initialization),即对象构造时所需资源应在构造函数中初始化,对象析构时释放这些资源。这种范式意味着应该用类来封装和管理资源。现代C++提供的智能指针,正是用于实现RAII手法。智能指针是存储指向动态分配对象指针的类,用于生命期控制,能够确保智能指针离开作用域时,自动正确地销毁动态分配地对象,防止内存泄漏。正确地使用智能指针后,理论上程序中应该不会再出现delete,也不用担心内存泄漏问题了。
关于scopeguard技术的讨论见stackoverflow:
Does ScopeGuard use really lead to better code?
某老外激情答复:
If there is one single piece of C++ code that I could recommend every C++ programmer spend 10 minutes learning, it is ScopeGuard (now part of the freely available Loki library).
I decided to try using a (slightly modified) version of ScopeGuard for a smallish Win32 GUI program I was working on. Win32 as you may know has many different types of resources that need to be closed in different ways (e.g. kernel handles are usually closed with CloseHandle()
, GDI BeginPaint()
needs to be paired with EndPaint()
, etc.) I used ScopeGuard with all these resources, and also for allocating working buffers with new
(e.g. for character set conversions to/from Unicode).
What amazed me was how much shorter the program was. Basically, it's a win-win: your code gets shorter and more robust at the same time. Future code changes can't leak anything. They just can't. How cool is that?
ScopeGuard 介绍和实现
未完待续...