C++ で RAII を使用する方法を学びたいです。それが何であるかはわかっていると思いますが、プログラムに実装する方法がわかりません。簡単な Google 検索では、適切なチュートリアルは表示されませんでした。
RAII を教えてくれる素敵なリンクはありますか?
何もありません (つまり、完全なチュートリアルは必要ないと思います)。
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)
)。
RAII のトピックに関して個人的に最も役立つ参考文献は、Herb Sutter によるExceptional C++という本です。
この本で取り上げられているトピックの多くは、Sutter による Guru of the Week の記事で触れられています。これらの記事はhttp://gotw.ca/gotw/index.htmで入手できます。
ウィキペディアの説明は悪くありません。
「Effective C+」の項目13もかなり役に立ちます