次の方法で共有


例外処理 : 古いコードの変換

更新 : 2007 年 11 月

この情報は上級者が対象です。

ここでは TRYCATCHTHROW などの Microsoft Foundation Class マクロで書かれた既存のコードを trycatch、throw などの C++ の例外処理用のキーワードに書き直す方法について説明します。ここでは、次の内容について説明します。

  • 変更によって得られる利点

  • 例外マクロから C++ の例外キーワードへのコード変換

変更によって得られる利点

マクロ ベースの例外処理を使った既存のプログラムは、ほとんどの場合、そのまま使用できます。ただし、MFC 3.0 におけるマクロの実装は以前のバージョンと異なるので、互換性が失われる場合は、コードを変換する必要があります。この実装の違いとその結果起こるマクロの動作の違いについては、「例外処理 : MFC 3.0 での変更点」を参照してください。

C++ 例外処理に変更すると、以下の利点があります。

  • C++ の例外処理用のキーワードを使ったプログラムをコンパイルすると、.EXE ファイルと .DLL ファイルが小さくなります。

  • C++ の例外処理用のキーワードの方が、広範囲に適用できます。つまり、コピー可能な任意のデータ型の例外を扱えます (int、float、char など)。一方、マクロで扱える例外は、CException クラスかその派生クラスの例外だけです。

マクロと C++ のキーワードの主な違いは、マクロを使ったコードでは、スコープから出るとキャッチされた例外が "自動的" に削除されることです。キーワードを使ったコードでは自動的に削除されないので、キャッチされた例外を明示的に削除する必要があります。詳細については、「例外処理 : 例外のキャッチと削除」を参照してください。

構文も異なります。次の 3 点が異なります。

  1. マクロの引数と例外の宣言

    CATCH マクロの構文は、次のとおりです。

    CATCH(exception_class, exception_object_pointer_name)

    クラス名とオブジェクトへのポインタの名前の間にコンマを挿入します。

    catch キーワードによる例外の宣言は、次のとおりです。

    catch(exception_typeexception_name)

    このステートメントは、catch ブロックで処理する例外の型を指定します。

  2. catch ブロックの区切り

    マクロの場合は、CATCH マクロ (とその引数) で最初の catch ブロックが始まります。AND_CATCH マクロで以降の catch ブロックが始まります。END_CATCH マクロで一連の catch ブロックを終了します。

    キーワードの場合は、catch キーワード (とその例外宣言) で各 catch ブロックが始まります。END_CATCH マクロに相当するものはなく、右中かっこで catch ブロックが終了します。

  3. throw 式

    マクロの場合は、現在処理中の例外を再スローするには THROW_LAST を使います。throw キーワードを引数なしで実行すると、同じ結果になります。

コードの変換

マクロを使ったコードを C++ の例外処理用キーワードを使ったコードに変換するには

  1. MFC マクロ TRYCATCHAND_CATCHEND_CATCHTHROW、および THROW_LAST のすべての出現箇所を探し出します。

  2. 以下のマクロをすべて置き換えるか削除します。

    TRY (try で置き換え)

    CATCH (catch で置き換え)

    AND_CATCH (catch で置き換え)

    END_CATCH (削除)

    THROW (throw で置き換え)

    THROW_LAST (throw で置き換え)

  3. 有効な例外宣言になるように、マクロの引数を書き換えます。

    たとえば、次のマクロは、

    CATCH(CException, e)
    

    次のように書き換えます。

    catch(CException* e)
    
  4. catch ブロックのコードを変更して、例外オブジェクトを適宜削除します。詳細については、「例外処理 : 例外のキャッチと削除」を参照してください。

次に、MFC 例外マクロを使ったコード例を示します。マクロを使っているので、式 e は自動的に削除されます。

TRY
{
   // Do something to throw an exception.
   AfxThrowUserException();
}
CATCH(CException, e)
{
   if (m_bPassExceptionsUp)
      THROW_LAST();

   if (m_bReturnFromThisFunction)
      return;

   // Not necessary to delete the exception e.
}
END_CATCH

次に、C++ 例外キーワードで書いたコード例を示します。式を明示的に削除する必要があります。

try
{
   // Do something to throw an exception.
   AfxThrowUserException();
}
catch(CException* e)
{
   if (m_bPassExceptionsUp)
      throw;

   if (m_bThrowDifferentException)
   {
      e->Delete();
      throw new CMyOtherException;
   }

   if (m_bReturnFromThisFunction)
   {
      e->Delete();
      return;
   }

   e->Delete();
}

詳細については、「例外処理 : MFC マクロと C++ 例外機構の使用」を参照してください。

参照

概念

例外処理 (MFC)