2010-06-28 2 views
17

Wikipedia говорит, что «кусок кода считается безопасным для исключений, если ошибки во время выполнения в коде не приведут к вредным последствиям, таким как утечка памяти, искаженные сохраненные данные или недопустимый вывод. Код, безопасный для исключения, должен удовлетворять инвариантам, помещенным в код, даже если происходят исключения ».Исключение безопасности в Qt

И, похоже, нам нужна обработка исключений для безопасности исключений. С другой стороны, обработка исключений не очень популярна в приложениях Qt, пока я вижу.

Каковы ваши лучшие практики в Qt для обеспечения безопасности исключений? Что вы используете вместо обработки исключений?

+1

QT - очень старая библиотека и очень бедна, когда дело доходит до безопасности исключений. Посмотрите, как все виджеты должны быть выделены в виде кучи, но для RAII нет умного указателя. Лучшее, что вы можете сделать, это выделить их в auto_ptr и освободить память родительскому/макету при вставке.У них есть некоторые основные положения, такие как QMutexLocker, поскольку бросок, когда блокировка мьютекса заблокирована, будет катастрофической, но есть намного больше, что им нужно для обеспечения или много работы, которую вы должны будете сделать сами, чтобы использовать qt безопасным способом , – stinky472

+8

@ stinky472: Неправильно. [QSharedPointer] (http://doc.trolltech.com/4.6/qsharedpointer.html) – MSalters

+0

@ stinky472: Какие инструменты GUI позволяют виджетам выделяться в стек? И почему вы хотите это сделать? Звучит как «соломенный» аргумент. – kevinarpe

ответ

10

C++ имеет очень мощный механизм для excpetion-безопасности. Деструкторы запускаются для всех переменных, выходящих за рамки из-за исключения. Это отличается от таких языков, как Java, где защита исключений требует, чтобы программист правильно добрался до catch и finally.

C++ поведение вызывающих деструкторов работает без проблем с объектами Qt в стеке. Все классы Qt имеют деструкторы, и ни одна из них не требует ручной очистки. Кроме того, QSharedPointer<T> может использоваться для управления выделенными кучей Qt-объектами; когда последний указатель выходит за пределы области, объект уничтожается. Это включает случай, когда указатель выходит за пределы видимости из-за исключения.

Таким образом, исключение-безопасность, безусловно, присутствует в Qt. Это просто прозрачно.

+2

Я думаю, что проблема с QSharedPointer заключается в том, что она не используется во многих местах. Например, QLayout ожидает QWidget * с ожиданием того, что QLayout станет менеджером памяти для него. Мы не можем использовать QSharedPointer здесь, потому что QLayout должен удалить виджет, когда он удален из макета. :-( – stinky472

+3

Исходное сообщение автора указано: «Обработка исключений не очень популярна в приложениях Qt, пока я вижу», что точно верно. Существование QSharedPointer ничего не меняет, потому что некоторые части QT API и его примеры фактически используют его Вместо этого у нас есть такие примеры, как QButton * button = new QButton (...); QVBoxLayout * layout = new QVBoxLayout (...); библиотека по большей части не закодирована как безопасная для исключений. должны быть решены, и принятие большего количества частей библиотеки и сохранение QSharedPointer было бы очень хорошим решением. – stinky472

2

Моя лучшая практика заключается в том, чтобы не использовать (или, по крайней мере, избегать их как можно больше). Исключения на C++ в коде на основе Qt, что делает обработку их проблемой без проблем. Qt на самом деле не причина этого, но я просто чувствую, что исключения часто делают вещи излишне сложными, чем они должны быть. Но это помогает сама Qt в основном исключение неприятности бесплатно ... :)

7

Qt (в основном) не исключение в безопасности: http://doc.qt.io/archives/4.6/exceptionsafety.html

С другой стороны, дело с исключениями правильно управляемых событиями программирования очень трудно , поэтому наилучшим образом должен избегать их при использовании Qt и передавать коды ошибок.

+10

Зачем правильно обрабатывать исключения в программировании, управляемом событиями, очень сложно? – metdos

1

Классы Qt: exception neutral, как указано в documentation.

Вы должны придерживаться логических значений для обработки условий ошибки, как и сам Qt.

Не использование исключений внутренне было сделано по соображениям переносимости, поскольку Qt должен поддерживать множество разных платформ (переносимость и исключения не очень хорошо смешиваются).

Опять же, из документации:

В настоящее время поддерживается только случай использования для извлечения из исключений выброшенных внутри Qt (например, из-за недостатка памяти), чтобы выйти из цикла обработки событий и сделать некоторые очистки, перед выходя из приложения. Типичный случай использования:

QApplication app(argc, argv); 
... 
try { 
    app.exec(); 
} catch (const std::bad_alloc &) { 
    // clean up here, e.g. save the session 
    // and close all config files. 

    return 0; // exit the application 
} 
+4

Обратите внимание, что Qt имеет историю, которая восходит к тому времени, когда исключения были новыми. Переносимость в XXI веке намного проще. – MSalters

+0

Вы правы, я должен был это подчеркнуть. Хотя я действительно мало знаю об исключениях и Symbian, особенно с более новыми версиями. Я знаю, что более старые версии используют существенно другой механизм обработки исключений. –

+0

Symbian - это боль; не удивительно, учитывая его корни EPOC 1980-х годов. Но Qt и Symbian не связаны с этим. Symbian создан в Psion; Qt в TrollTech. – MSalters

Смежные вопросы