これは高度なトピックです。
この記事では、Microsoft Foundation Class マクロ ( TRY、 CATCH、 THROW など) で記述された既存のコードを変換して、C++ 例外処理キーワードの try
、 catch
、 throw
を使用する方法について説明します。 ここでは、次の内容について説明します。
変換の利点
MFC バージョン 3.0 のマクロ実装と以前のバージョンの実装の違いに注意する必要がありますが、おそらく既存のコードを変換する必要はありません。 これらの違いとコード動作の後続の変更については、「 例外: バージョン 3.0 での例外マクロの変更」で説明されています。
変換の主な利点は次のとおりです。
C++ 例外処理キーワードを使用するコードは、少し小さい.EXEまたは.DLLにコンパイルされます。
C++ 例外処理キーワードは、より汎用的です。コピーできる任意のデータ型 (
int
、float
、char
など) の例外を処理するのに対し、マクロはクラスCException
およびそこから派生したクラスの例外のみを処理します。
マクロとキーワードの主な違いは、マクロを使用するコードは、例外がスコープ外になったときにキャッチされた例外を "自動的に" 削除することです。 キーワードを使用するコードでは実行されないため、キャッチされた例外を明示的に削除する必要があります。 詳細については、「 例外: 例外のキャッチと削除」を参照してください。
もう 1 つの違いは構文です。 マクロとキーワードの構文は、次の 3 つの点で異なります。
マクロ引数と例外宣言:
CATCH マクロの呼び出しには、次の構文があります。
CATCH(exception_class, exception_object_pointer_name)
クラス名とオブジェクト ポインター名の間のコンマに注意してください。
catch
キーワードの例外宣言では、次の構文が使用されます。catch(exception_typeexception_name)
この例外宣言ステートメントは、catch ブロックが処理する例外の種類を示します。
catch ブロックの区切り:
マクロを使用すると、 CATCH マクロ (引数を含む) が最初の catch ブロックを開始します。 AND_CATCH マクロは後続の catch ブロックを開始し、 END_CATCH マクロは catch ブロックのシーケンスを終了します。
キーワードを使用すると、(例外宣言を含む)
catch
キーワードが各 catch ブロックを開始します。 END_CATCH マクロに対応するマクロはありません。catch ブロックは右中かっこで終わります。throw 式:
マクロは 、THROW_LAST を使用して現在の例外を再スローします。 引数を指定しない
throw
キーワードも同じ効果を持ちます。
変換の実行
マクロを使用してコードを変換して C++ 例外処理キーワードを使用するには
MFC マクロ TRY、CATCH、AND_CATCH、END_CATCH、THROW、THROW_LASTのすべての出現箇所を見つけます。
次のマクロのすべての出現箇所を置換または削除します。
TRY (
try
に置き換えます)CATCH (
catch
に置き換えます)AND_CATCH (
catch
に置き換えます)END_CATCH (削除)
THROW (
throw
に置き換えます)THROW_LAST (
throw
に置き換えます)有効な例外宣言を形成するようにマクロ引数を変更します。
たとえば、
CATCH(CException, e)
送信先
catch (CException* e)
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++ 例外の使用」を参照してください。