ここで説明されている他の回答に、カスタム例外の場合の追加のメモを追加したかった。
から派生する独自のカスタム例外を作成する場合、std::exception
「すべての可能な」例外タイプをキャッチするときは、常に、キャッチされる可能性のcatch
ある「最も派生した」例外タイプで句を開始する必要があります。(何をしてはいけないか)の例を見てください:
#include <iostream>
#include <string>
using namespace std;
class MyException : public exception
{
public:
MyException(const string& msg) : m_msg(msg)
{
cout << "MyException::MyException - set m_msg to:" << m_msg << endl;
}
~MyException()
{
cout << "MyException::~MyException" << endl;
}
virtual const char* what() const throw ()
{
cout << "MyException - what" << endl;
return m_msg.c_str();
}
const string m_msg;
};
void throwDerivedException()
{
cout << "throwDerivedException - thrown a derived exception" << endl;
string execptionMessage("MyException thrown");
throw (MyException(execptionMessage));
}
void illustrateDerivedExceptionCatch()
{
cout << "illustrateDerivedExceptionsCatch - start" << endl;
try
{
throwDerivedException();
}
catch (const exception& e)
{
cout << "illustrateDerivedExceptionsCatch - caught an std::exception, e.what:" << e.what() << endl;
// some additional code due to the fact that std::exception was thrown...
}
catch(const MyException& e)
{
cout << "illustrateDerivedExceptionsCatch - caught an MyException, e.what::" << e.what() << endl;
// some additional code due to the fact that MyException was thrown...
}
cout << "illustrateDerivedExceptionsCatch - end" << endl;
}
int main(int argc, char** argv)
{
cout << "main - start" << endl;
illustrateDerivedExceptionCatch();
cout << "main - end" << endl;
return 0;
}
注意:
0)適切な順序は逆、つまり最初にあなたのcatch (const MyException& e)
後にが続く必要がありますcatch (const std::exception& e)
。
であるとして、あなたがプログラムを実行するとき1)あなたが見ることができるように、最初のcatch句は、あなたが何をしたか、おそらくである(実行されますしないで)最初の場所にしたかったです。
2)最初のcatch句でキャッチされた型がtypeであってもstd::exception
、「適切な」バージョンのwhat()
が呼び出されます-参照によってキャッチされるため(少なくともキャッチされた引数のstd::exception
型を値によって変更することで)、動作中の「オブジェクトのスライス」現象)。
3)「XXX例外がスローされたために一部のコードが例外タイプに対して重要な処理を行う」場合、ここにコードの不正な動作があります。
4)これは、キャッチしたオブジェクトが次のような「通常の」オブジェクトである場合にも関連class Base{};
しclass Derived : public Base {}
ます。
5)g++ 7.3.0
Ubuntu 18.04.1では、上記の問題を示す警告が表示されます。
関数 'void IllustrateDerivedExceptionCatch()'で:item12Linux.cpp:48:2:警告:タイプ 'MyException'の例外がキャッチされますcatch(const MyException&e)^ ~~~~
item12Linux.cpp:43:2:警告: 'std :: exception'
キャッチの初期ハンドラー(const例外&e)^ ~~~~
繰り返しますが、この回答は、ここで説明されている他の回答に追加することのみを目的としています(この点は言及する価値があると思いましたが、コメント内に描写することはできませんでした)。