私は開発中のC++アプリケーションの例外クラスの小さな階層を作成しており、間接的にはstd::runtime_error
から派生しています。ここで私はこれまでに書かれたものに類似したコードは次のとおりです。デフォルトのコンストラクタを持たない仮想ベースからクラスを派生させよう
class RuntimeException : public virtual boost::exception, public virtual std::runtime_error {
public:
virtual ~RuntimeException() {}
RuntimeException() : runtime_error("A RuntimeException occurred.") {}
RuntimeException(const std::string& what) : runtime_error(what) {}
};
class IllegalArgumentException : public virtual RuntimeException {
public:
IllegalArgumentException() : RuntimeException("An IllegalArgumentException occurred.") {}
IllegalArgumentException(const std::string& what) : RuntimeException(what) {}
};
RuntimeException
クラスは問題なくコンパイルが、エラー生成し、VS2015でコンパイルするIllegalArgumentException
を拒否:IllegalArgumentException
の両方のコンストラクタのためno default constructor exists for class "std::runtime_error"
を。これは、私はこのコードがうまくコンパイルされると期待していたので、C++の継承階層の理解には挑戦しています。
私の理解では、それがstd::runtime_error
は、デフォルトコンストラクタを持っていないことは事実ですが、そのコンストラクタはRuntimeException
ためにコンストラクタによって呼び出されている、のでIllegalArgumentException
がコンパイルする必要があることです。しかし、コンパイラがそれを拒否しているので、明らかにこれはfalseでなければならない。 IllegalArgumentException
コンストラクタから直接std::runtime_error
コンストラクタを呼び出すことを望んでいるようですが(コンパイラエラーが消えてしまいます)、これはコンストラクタをの2回呼び出すので間違っています:RuntimeException
のコンストラクタで、 IllegalArgumentException
のコンストラクタで再度呼び出します。
これは安全かつ効率的ですか?そうでない場合、なぜコンパイラはそれを推奨しているようですか?私はstd::exception
から派生し、std::string
自分自身をメンバ変数として実装していますが、すでにこれを実装している標準クラスから派生する方が簡単だと思いました。これは間違ったアプローチですか?さらに、私がこの問題に寄与するboost:exception
とstd::runtime_error
の両方から事実上派生しているという事実はありますか?
ありがとう、あなたの説明は非常に明確です。これを踏まえて、私は 'std :: exception'から派生し、自分自身の' std :: string'を使って終わる可能性が最も高いです。それは行くのが一番簡単な方法です。 –