Исключение безопасности в Qt

17

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

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

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

    
задан metdos 28.06.2010 в 09:37
источник
  • QT - очень старая библиотека и очень бедна, когда дело касается безопасности исключений. Посмотрите, как все виджеты должны быть выделены в виде кучи, но для RAII нет умного указателя. Лучшее, что вы можете сделать, это выделить их в auto_ptr и освободить память родительскому / макету при вставке. У них есть некоторые основные положения, такие как QMutexLocker, поскольку бросок, когда блокировка мьютекса заблокирована, будет катастрофической, но есть намного больше, что им нужно для обеспечения или много работы, которую вы должны будете сделать сами, чтобы использовать qt безопасным способом , –  stinky472 28.06.2010 в 15:59
  • @ stinky472: Неверно. QSharedPointer –  MSalters 28.06.2010 в 16:25
  • @ stinky472: Какие инструменты GUI позволяют виджетам выделяться в стек? И почему вы хотите это сделать? Звучит как «соломенный» аргумент. –  kevinarpe 30.12.2011 в 09:50
  • @KCArpe В заявлении говорилось: «Рассмотрите, как все виджеты должны быть выделены в виде кучи ***, но нет никакого умного указателя для RAII». Я не жалуюсь на то, что виджеты выделены в виде кучи, что становится весьма существенным благодаря дизайну, основанному на наследовании и полиморфизме, таком как QT. Я жалуюсь на отсутствие RAII и безопасность исключений в модели управления памятью QT. –  stinky472 31.01.2012 в 20:42
  • Просто рассмотрите этот базовый пример из официальных документов QT: menuBar = new QMenuBar; fileMenu = new QMenu (tr («& File»), это); Что произойдет, если оператор new бросит на создание fileMenu? Упс, утечка памяти. Таким образом, QT не предназначен для безопасности исключений. Даже примеры Nokia неверны с точки зрения безопасности исключений. –  stinky472 31.01.2012 в 20:46
Показать остальные комментарии

4 ответа

10

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

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

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

    
ответ дан MSalters 28.06.2010 в 10:38
  • Я думаю, что проблема с QSharedPointer заключается в том, что она не используется во многих местах. Например, QLayout ожидает QWidget * с ожиданием того, что QLayout станет менеджером памяти для него. Мы не можем использовать QSharedPointer здесь, потому что QLayout должен удалить виджет, когда он удален из макета. :-( –  stinky472 31.01.2012 в 20:50
  • В оригинальной публикации автора указано: «Обработка исключений не очень популярна в приложениях Qt, пока я вижу», что точно верно. Существование QSharedPointer ничего не меняет, потому что на самом деле его используют некоторые части QT API и его примеры. Вместо этого у нас есть такие примеры, как QButton * button = new QButton (...); QVBoxLayout * layout = new QVBoxLayout (...); Библиотека по большей части не закодирована как безопасная для исключений. Это то, что нужно решать, и принятие большего количества частей библиотеки и сохранение QSharedPointer было бы очень хорошим решением. –  stinky472 01.02.2012 в 16:26
7

Qt (в основном) не исключение: Ссылка

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

    
ответ дан Artyom 28.06.2010 в 10:06
  • Почему правильно работать с исключениями в программировании, управляемом событиями, очень сложно? –  metdos 07.04.2011 в 15:37
2

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

    
ответ дан Xenakios 28.06.2010 в 09:51
1

Классы Qt составляют exception neutral , как указано в документации .

Вы должны придерживаться логических значений для обработки условий ошибки, как и сам 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
 }
    
ответ дан the_void 28.06.2010 в 10:06
  • Обратите внимание, что Qt имеет историю, которая восходит к тому времени, когда исключения были новыми. Переносимость в XXI веке намного проще. –  MSalters 28.06.2010 в 10:30
  • Вы правы, я должен был это подчеркнуть. Хотя я действительно мало знаю об исключениях и Symbian, особенно с более новыми версиями. Я знаю, что более старые версии используют существенно другой механизм обработки исключений. –  the_void 28.06.2010 в 10:48
  • Symbian - это боль; не удивительно, учитывая его корни EPOC 1980-х годов. Но Qt и Symbian не связаны друг с другом. Symbian создан в Psion; Qt в TrollTech. –  MSalters 28.06.2010 в 16:34