38

我想学习如何在 C++ 中使用 RAII。我想我知道它是什么,但不知道如何在我的程序中实现它。快速的谷歌搜索没有显示任何好的教程。

有没有人有任何很好的链接来教我 RAII?

4

4 回答 4

34

这没什么(也就是说,我认为您不需要完整的教程)。

RAII 可以简单地解释为“每个需要清理的资源都应该交给对象的构造函数”。

换句话说:

指针应封装在智能指针类中(参见 std::auto_ptr、boost::shared_ptr 和 boost::scoped_ptr 示例)。

需要清理的句柄应封装在销毁时自动释放/释放句柄的类中。

同步应该依赖于在范围退出时释放互斥锁/同步原语(参见 boost::mutex::scoped_lock 使用示例)。

我不认为你真的可以有一个关于 RAII 的教程(例如你可以有一个关于设计模式的教程)。RAII 更多的是一种查看资源的方式。

例如,目前我正在使用 WinAPI 进行编码,并编写了以下类:

template<typename H, BOOL _stdcall CloseFunction(H)>
class checked_handle
{
public:
    typedef checked_handle<H,CloseFunction> MyType;
    typedef typename H HandleType;

    static const HandleType     NoValue;

    checked_handle(const HandleType value)
        : _value(value)
    {
    }

    ~checked_handle()
    {
        Close();
    }

    HandleType* operator &()
    {
        return &_value;
    }

    operator HandleType()
    {
        return _value;
    }

private:
    HandleType      _value;

    void Close(const HandleType newValue = NoValue)
    {
        CloseFunction(_value);
        _value = newValue;
    }
};

template<typename H,BOOL _stdcall CloseFunction(H)>
const typename checked_handle<H,CloseFunction>::HandleType 
    checked_handle<H,CloseFunction>::NoValue = 
    checked_handle<H,CloseFunction>::HandleType(INVALID_HANDLE_VALUE);

typedef checked_handle<HANDLE,::CloseHandle> CheckedHandle;
typedef checked_handle<HWINSTA,::CloseWindowStation> WinStationHandle;
typedef checked_handle<HDESK,::CloseDesktop> DesktopHandle;
typedef checked_handle<HDEVNOTIFY,::UnregisterDeviceNotification> DevNotifyHandle;
typedef checked_handle<HWND,::DestroyWindow> WindowHandle;

BOOL __stdcall CloseKey(HKEY hKey);
typedef checked_handle<HKEY,CloseKey> RegHandle;

这个类不包括赋值和复制语义(我删除了它们以提供一个最小的例子)所以按值返回,将导致句柄被关闭两次。

以下是它的使用方法:

类声明:

class Something
{
public:
    // ...
private:
    WindowHandle        _window;
};

该成员已分配,但我从不明确调用(当实例超出范围::CloseWindow(_window._handle)时将调用它(如-> -> )。SomethingSomething::~SomethingWindowHandle::WindowHandle::Close(_window._value)

于 2010-04-14T11:26:14.707 回答
3

维基百科的解释还不错。

于 2010-04-14T08:28:57.740 回答
3

我个人认为对 RAII 主题最有帮助的参考资料是Herb Sutter所著的Exceptional C++一书。

Sutter 的“本周大师”文章中提到了该书中涵盖的许多主题。这些文章可在http://gotw.ca/gotw/index.htm获得。

于 2010-04-14T08:47:17.550 回答
2

《Effective C+》的第 13 条也很有用

于 2010-09-24T05:48:56.323 回答