例外処理の安全性
事前警告:例外処理の安全性に関する機能は、まだ完全には実装されていません!一般的なケースでは動作するはずですが、クラスからのリークが発生したり、場合によってはクラッシュしたりする可能性があります。
Qt自体は例外をスローしません。その代わりに、エラーコードが使用されます。また、一部のクラスには、QIODevice::errorString()やQSqlQuery::lastError()など、ユーザーに表示されるエラーメッセージが用意されています。これには歴史的および実用的な理由があります。例外処理を有効にすると、ライブラリのサイズが20%以上増加する可能性があるためです。
以下のセクションでは、コンパイル時に例外処理が有効になっている場合の Qt の動作について説明します。
例外セーフなモジュール
コンテナ
Qtのコンテナクラスは、一般的に例外中立です。これらは、内部状態を有効なまま維持しつつ、包含される型T 内で発生したあらゆる例外をユーザーに伝達します。
例:
QList<QString> list;
...
try {
list.append("hello");
} catch (...) {
}
// list is safe to use - the exception did not affect it.この規則の例外となるのは、代入やコピーコンストラクタの処理中に例外をスローする可能性のある型用のコンテナです。これらの型の場合、コンテナを修正する関数や値を返す関数の使用は安全ではありません:
MyType s = list.takeAt(2);s の代入中に例外が発生した場合、インデックス2の位置にある値はすでにコンテナから削除されていますが、s にはまだ代入されていません。この値は回復不可能な状態で失われてしまいます。
正しい記述方法は次のとおりです:
MyType s = list.at(2);
list.removeAt(2);代入時に例外が発生した場合でも、コンテナにはその値が残っており、データの損失は発生しません。
なお、暗黙的に共有されるQtクラスは、代入演算子やコピーコンストラクタ内で例外を投げないため、上記の制限は適用されません。
メモリ不足時の処理
ほとんどのデスクトップオペレーティングシステムでは、メモリのオーバーコミットが行われます。つまり、割り当て時に利用可能なメモリが不足していても、malloc() やoperator new は有効なポインタを返します。このようなシステムでは、std::bad_alloc 型の例外はスローされません。
その他のすべてのオペレーティングシステムでは、割り当てに失敗した場合、Qtは std::bad_alloc 型の例外をスローします。割り当てが失敗するのは、システムのメモリが不足している場合や、要求されたサイズを割り当てるのに十分な連続したメモリがない場合などです。
この規則の例外については、ドキュメントに記載されています。例えば、QImage のコンストラクタは、十分なメモリが存在しない場合、例外をスローする代わりにnull 画像を作成します。
例外からの回復
現在、Qt 内でスローされた例外(メモリ不足など)からの回復としてサポートされているユースケースは、イベントループを終了し、アプリケーションを終了する前にクリーンアップ処理を行うことのみです。
典型的なユースケース:
QApplication app(argc, argv);
...
int ret;
try {
ret = app.exec();
} catch (const std::bad_alloc &) {
// clean up here, e.g. save the session
// and close all config files.
return EXIT_FAILURE; // exit the application
}
...
return ret;例外がスローされた後、ウィンドウサーバーへの接続はすでに切断されている可能性があります。例外をキャッチした後にGUI関連の関数を呼び出すことは安全ではありません。
クライアントコードにおける例外
シグナルとスロット
Qtのシグナル・スロット接続メカニズムによって呼び出されたスロットから例外をスローすることは、そのスロット内で処理されない限り、未定義の挙動と見なされます:
State state;
StateListener stateListener;
// OK; the exception is handled before it leaves the slot.
QObject::connect(&state, SIGNAL(stateChanged()), &stateListener, SLOT(throwHandledException()));
// Undefined behaviour; upon invocation of the slot, the exception will be propagated to the
// point of emission, unwinding the stack of the Qt code (which is not guaranteed to be exception safe).
QObject::connect(&state, SIGNAL(stateChanged()), &stateListener, SLOT(throwUnhandledException()));通常の関数呼び出しのようにスロットが直接呼び出された場合、例外を使用することができます。これは、スロットを直接呼び出す際には接続メカニズムがバイパスされるためです:
State state;
StateListener stateListener;
// ...
try{
// OK; スロットを直接呼び出しています。
stateListener.throwException();
}catch(...) {
qDebug() << "Handling exception not caught in slot.";
}© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.