5

例外と多重継承の混合に問題があります。基本的に私はこのコードを持っています:

#include <exception>
#include <stdexcept>
#include <iostream>

class A : public std::exception
{
public:
    virtual ~A() noexcept {};
};

class B : public A, public std::runtime_error
{
public:
    B() : A{}, std::runtime_error{""}
    {

    }
};

int main()
{
    try {
        throw B{};
    } catch (const std::exception& error) {
        // this catch doesn't work
        std::clog << "Caught!" << std::endl;
    }
}

私が必要としているのは、クラスBの例外をstd :: exceptionとしてキャッチできるように変更することです(今のところ、terminateハンドラーが呼び出されます)。どうすればそのような動作を実現できますか?仮想継承が必要だと思いますが、この場合は仮想継承を使用する方法がわかりません。

更新:次のことができる必要があります:
-AをAとしてキャッチ(トリビアル)、
-Aをstd :: exceptionとして
キャッチ、-BをBとしてキャッチ(再び、トリビアル)、
-Bをstd :: exceptionとしてキャッチ、-Bを
キャッチstd::runtime_errorとして

私はこれが多くの要件であることを知っています、そして多分それはあまり意味がありません、しかし私はそれを必要とします、そして私はただ興味があります:)

UPDATE2:問題はstd ::runtime_errorがstd::exceptionから仮想的に派生していないことだと思います(これにより、Aの仮想継承によって問題を解決できます)。私は正しいですか?それでも、それは解決できますか?

UPDATE3:Alan Stokesは、以下のコメントで解決策を提案しました。これは私にとってはうまくいくようです。

Aを2つのクラスに分割できますか?1つはBが必要とする機能を実装し、もう1つはstd :: exceptionからの継承を追加しますか?次に、AとBの両方が(たとえば)A_baseから継承できます。

それでも、他に良い解決策があれば教えてください。

4

1 に答える 1

4

Stroustrup はstd::exception、変換パスが 1 つだけになるように、仮想から継承することを推奨しています。

個人的には、複数の継承スキームを構築することはおそらくオーバーエンジニアリングであり、線形の継承チェーンを好むと思います...またはまったく継承しない.

于 2012-07-14T15:45:11.200 に答える