2010-11-02 3 views
2

Я делаю C++ игру gui lib и задаюсь вопросом, когда я должен бросать исключения. Прямо сейчас, например, если я получаю указатель NULL, функция бесшумно терпит неудачу. Должен ли я вместо этого делать исключение? Это не то, что на самом деле заставило бы его рухнуть. Каковы примеры хороших мест для исключения исключений?Когда следует исключать исключения?

благодаря

+4

Все, что лучше, чем бесшумно. –

+1

Если вы пишете библиотеку, вы можете повторно использовать ее в будущем или распространять ее друзьям/коллегам. Лично я бросаю исключения повсюду, чтобы дать мне гибкость в обращении с ним или игнорировать его в конечном приложении, в отличие от молчания в библиотеке. – dotalchemy

+0

Лучше, почему вы используете указатель вместо ссылки, особенно если вы должны ссылаться на действительный объект. – GManNickG

ответ

11

Обычный ответ на этот вопрос заключается в том, что вы должны делать исключения только в «исключительных» обстоятельствах. Но каковы исключительные обстоятельства. Некоторые примеры:

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

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

Эта тема была затронута на этом сайте и в другом месте, поэтому поиск в Google с использованием вашего названия вызовет множество примеров и комментариев.

Что касается вашего конкретного приложения - возможно, возьмитесь за api для некоторых других игр gui libs, чтобы понять, как работают эти библиотеки (если вы считаете, что они хорошо разработаны).

0

Это полностью зависит от того, что вы делаете и что вы хотите использовать свой код в будущем.

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

Silent failing - худшая идея, которую я слышу, если вы говорите о написании библиотеки.

3

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

0

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

Было время, когда вы не могли быть уверены в том, что исключение действительно будет поймано, если код, выполняющий ловушку, не был создан той же версией того же самого компилятора с теми же флагами, что и код, бросающий исключение. Это, по-видимому, было в значительной степени решено на платформах, которые имеют de facto стандарт ABI. Но как только я привык сообщать о сбоях в библиотечном коде без исключений, я обнаружил, что есть веские причины продолжать это делать.

Во-первых, библиотеки предназначены для использования третьими лицами, и эти стороны, возможно, не слишком волнуются о writing exception safe code.

Исключительный безопасный код касается не только управления ресурсами. Рассмотрим:

... 
// m is a mutex 
boost::scoped_lock(m); // now I can't forget to release the mutex 
withdraw_money(acct1, 1000); 
function_that_may_throw_exception(); 
deposit_money(acct2, 1000); 

Конечно, это можно переписать так:

// using Boost SCOPE_EXIT 
bool commit = false; 
boost::scoped_lock(m); 
withdraw_money(acct1, 1000); 
SCOPE_EXIT((&commit) (&acct1)) 
{ 
    if (!commit) { 
     deposit_money(acct1, 1000); 
    } 
} 

function_that_may_throw_exception(); 
deposit_money(acct2, 1000); 
commit = true; 

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

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