組み込み環境で作業している場合、おそらくごくわずかな解決策が優先され、コンパイラーに関する非標準または移植不可能な事実を利用できます。
クラスがポリモーフィック(それ自身の仮想関数が少なくとも1つあります)がC++であれば、その中にvtableへのポインタがある可能性があります。 vtableポインタがメモリ内のオブジェクトのレイアウトの先頭に表示されることがあります。
これは多くのコンパイラに当てはまりますが、これはC++ ABI-a related SO question hereを使用するコンパイラに当てはまります。
もしそうなら、あなたはこのようなvtableのに取得することができるかもしれない:
void *get_vtable(void *obj)
{
return *(reinterpret_cast<void **>(obj));
}
その後、あなたは、彼らは同じ型を指すかどうかを確認するために、2つのポインタ・ツー・オブジェクトのvtableをを比較することができますオブジェクトの。
だから、(基本的にされてキャッチするものです)「タイプのスイッチは、」このような何かをするだろう:
P p;
Q q;
if (get_vtable(caught) == get_vtable(&p))
{
// it's a P...
}
else if (get_vtable(caught) == get_vtable(&q))
{
// it's a Q...
}
あなたはCATCHマクロでそのパターンを隠すことができます。
重要なポイント - あなたはベースからクラスを派生ますが、派生クラスは、任意の仮想関数をオーバーライドしたり、任意の新しい仮想関数を追加しない場合、コンパイラが考えられる派生クラスの基本クラスのvtableのを再利用することができます。これは、2つの例外タイプを区別するために、それらがそれぞれ独自のvtableを持つことを保証するために、仮想関数をオーバーライドする必要があることを意味します。
これは、例外処理に関係する部分のごくわずかです。スタックを巻き戻すという小さな問題もあります!ハンドラにジャンプするときは、スタック上のすべてのオブジェクトのデストラクタを呼び出す必要があります。 setjmp/longjmpを実行するだけの問題ではありません。
コンパイラや言語ランタイムを記述したり変更したりしていますか、それとも正確にどこに収まるでしょうか?もう少し文脈がいい。 – jalf
メモリが限られている場合は、RTTIを有効にしたり、例外を使用したりしないでください。代わりのアプローチを考えてみてください。 –
例外がスローされた場合、何らかの方法でthrow nustが例外の型情報をエンコードしているため、なぜ「代替」メソッドが必要なのかわかりません。 jalfが言ったように、あなたが実際にやろうとしていることについてもっと多くの情報を与えてください。 –