違いは何ですか std::runtime_error
およびstd::exception
?それぞれの適切な用途は何ですか?そもそもなぜ違うのですか?
_std::exception
_は、例外階層で基本クラスとして機能することが唯一の目的であるクラスです。他の用途はありません。つまり、概念的にはabstractクラスです(C++の用語の意味で抽象クラスとして定義されていない場合でも)。
_std::runtime_error
_は、さまざまなruntimeエラーが発生した場合にスローされることを意図した、_std::exception
_から派生したより特殊なクラスです。二重の目的があります。単独でスローすることも、_std::range_error
_、_std::overflow_error
_など、さらに特殊なタイプのランタイムエラー例外の基本クラスとして機能することもできます。 _std::runtime_error
_、および_std::exception
_から派生した独自の例外クラスを定義できます。
_std::runtime_error
_と同様に、標準ライブラリには_std::logic_error
_が含まれており、これも_std::exception
_から派生しています。
この階層を持つことのポイントは、C++例外処理メカニズムの全機能を使用する機会をユーザーに与えることです。 「catch」句は多態性例外をキャッチできるため、ユーザーは例外階層の特定のサブツリーから例外タイプをキャッチできる「catch」句を作成できます。たとえば、catch (std::runtime_error& e)
は、_std::runtime_error
_サブツリーからのすべての例外をキャッチし、他のすべてをパススルーさせます(さらに呼び出しスタックをさらに上に飛ばします)。
追伸有用な例外クラス階層(コードの各ポイントで関心のある例外タイプのみをキャッチできるようにする)を設計するのは簡単なことではありません。標準C++ライブラリで見られるものは、言語の作成者によって提供される1つの可能なアプローチです。ご覧のように、彼らはすべての例外タイプを「実行時エラー」と「論理エラー」に分割し、そこから独自の例外タイプを進めることにしました。もちろん、その階層を構成する別の方法がありますが、これは設計でより適切な場合があります。
更新:Portability Linux vs Windows
Loki Astariとunixman83が以下の回答とコメントで述べたように、exception
クラスのコンストラクターはC++標準に従って引数を取りません。 Microsoft C++には、exception
クラスの引数を取るコンストラクタがありますが、これは標準ではありません。 _runtime_error
_クラスには、WindowsとLinuxの両方のプラットフォームで引数(_char*
_)をとるコンストラクターがあります。移植性を高めるには、_runtime_error
_を使用する方が適切です。
(そして、プロジェクトの仕様がコードをLinux上で実行する必要がないと言っているからといって、Linux上で実行する必要がないという意味ではないことを忘れないでください。)
std :: exceptionは、標準の例外階層の抽象ベースと見なされる(考慮されることに注意)必要があります。これは、特定のメッセージを渡すメカニズムがないためです(これを行うには、what()を派生および特殊化する必要があります)。 std :: exceptionの使用を止めることは何もありません。また、単純なアプリケーションの場合は、必要なものはすべて揃っています。
一方、std :: runtime_errorには、文字列をメッセージとして受け入れる有効なコンストラクターがあります。 what()が呼び出されると、コンストラクターに渡された文字列と同じ文字列を持つC文字列を指すconst charポインターが返されます。
try
{
if (badThingHappened)
{
throw std::runtime_error("Something Bad happened here");
}
}
catch(std::exception const& e)
{
std::cout << "Exception: " << e.what() << "\n";
}