C ++的RAII教程

时间:2010-04-14 08:25:18

标签: c++ raii

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

是否有人有任何好的链接教我RAII?

4 个答案:

答案 0 :(得分:27)

没有任何内容(也就是说,我认为你不需要完整的教程)。

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)(当Something的实例超出范围时(Something::~Something - &gt; WindowHandle::WindowHandle,将会调用此成员) &gt; ::Close(_window._value))。

答案 1 :(得分:3)

wikipedia解释并不错。

答案 2 :(得分:2)

我个人发现对RAII主题最有帮助的参考是Herb Sutter的书Exceptional C++

该书中涉及的许多主题都在萨特的“周刊大师”一文中被提及。这些文章可在http://gotw.ca/gotw/index.htm获得。

答案 3 :(得分:2)

"Effective C+"的第13项也非常有用