2007年09月12日

半歩進んだエラー処理

エラー処理って大事だけど面倒ですよね。初期化関数なんて真面目にエラー処理していたら、本来のコードよりもエラー処理の方が多くなったなんてのもよくある話です。

エラーコードやクラスを定義したりするのも面倒ですし、それらとエラーメッセージの対応を取るのも凄く面倒です。エラーが発生したかどうかだけが重要で、その内容はどうでもいい場合も多く、関数の戻り値をTRUE/FALSEやS_OK/E_FAILのように2値にしている方も多いと思います。

しかし、成功か失敗かの2値だけではほとんどデバッグの役に立ちませんし、各所でエラーメッセージを出そうとすると汚いコードになりがちです。いちいちエラーメッセージを出すのが面倒になって、全てのエラーを「初期化エラー」の一言で片付けていませんか?

そこで、半歩進んだエラー処理として、例外処理を使ったとても簡単な方法を紹介します。

エラー処理に例外処理を使うなんて、C++の入門書を見たら必ず書いてあることですが、どの本を見ても「例外クラスを定義して云々...」と小難しいことが書かれていて面倒です。しかし、ここで紹介する方法はとてもシンプル。エラーメッセージそのものを例外として投げるだけです。

この方法でDirect3Dの初期化を書くと次のようになります。


BOOL InitD3D(HWND hWnd)
{
    try
    {
        lpD3D = Direct3DCreate9(D3D_SDK_VERSION);
        if(lpD3D == NULL)
            throw _T("Can't create Direct3D object");
        if(FAILED(lpD3D->CreateDevice(/*省略*/, &lpD3DDev)))
            throw _T("Can't create Direct3DDevice object");
        return TRUE;
    }
    catch(LPCTSTR str)
    {
        MessageBox(NULL, str, _T("Error"), MB_ICONERROR|MB_OK);
        SAFE_RELEASE(lpD3DDev);
        SAFE_RELEASE(lpD3D);
        return FALSE;
    }
}

新しい種類のエラーが現れても、その場でエラーメッセージを定義するだけで、他の場所で例外クラスやエラーコードを定義する必要はありません。

この方法は非常に簡単で、これと同じことをこれより短く書くのは無理ではないかと思います。

ただし、この方法でエラーメッセージに変数の値も含めようとすると、ちょっと面倒になります。try句の中でスタック上に確保したバッファはcatch句に入る前に解放されてしまいますし、バッファを確保してsprintf等を呼んでいたのでは手軽さが損なわれてしまいます。どうしても変数をエラーメッセージに入れたいときは、printfのような書式からstringを返す関数等を用意するといいと思います。

タグ:C++
2007年09月12日 【プログラミング】 | コメント(0) |

この記事へのトラックバックURL


この記事へのトラックバック
この記事へのコメント

コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。