38

C++ で RAII を使用する方法を学びたいです。それが何であるかはわかっていると思いますが、プログラムに実装する方法がわかりません。簡単な Google 検索では、適切なチュートリアルは表示されませんでした。

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;

このクラスには割り当てとコピーのセマンティクスが含まれていないため (最小限の例を提供するためにそれらを削除しました)、値で返すと、ハンドルが 2 回閉じられます。

使用方法は次のとおりです。

クラス宣言:

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

このメンバーは割り当てられていますが、::CloseWindow(_window._handle)明示的に呼び出すことはありません (インスタンスがSomethingスコープ外に出たときに呼び出されます ( Something::~Something-> WindowHandle::WindowHandle->として::Close(_window._value))。

于 2010-04-14T11:26:14.707 に答える
3

RAII のトピックに関して個人的に最も役立つ参考文献は、Herb Sutter によるExceptional C++という本です。

この本で取り上げられているトピックの多くは、Sutter による Guru of the Week の記事で触れられています。これらの記事はhttp://gotw.ca/gotw/index.htmで入手できます。

于 2010-04-14T08:47:17.550 に答える
3

ウィキペディアの説明は悪くありません。

于 2010-04-14T08:28:57.740 に答える
2

「Effective C+」の項目13もかなり役に立ちます

于 2010-09-24T05:48:56.323 に答える