Страницы

Поиск по вопросам

понедельник, 6 января 2020 г.

Обработка ошибок c++

#java #cpp #исключения


Только начал изучать обработку ошибок на с++, но до этого был знаком с java. Вот
там работает такая конструкция:

try {
    int d = 2/0;
}
catch(ArithmeticException t) {
    System.out.println("Error!!!");
}


И сразу же захотелось реализовать что-нибудь подобное на с++, но к моему сожаление
я не обнаружил никаких готовых классов, кроме exception. Подскажите, пожалуйста, может
я где не доглядел, есть ли какие-нибудь готовые конструкции/классы? Как реализовать
подобную конструкцию на плюсах? Можно ли вообще создавать исключения без ключевого
слова throw?



Если есть ссылки с большим/хорошим материалом по обработке ошибок на c++, подкиньте,
пожалуйста.
Правильно ли я понимаю,что на c++ вообще нет ничего готового, как в java, и всё приходится
делать ручками?
    


Ответы

Ответ 1



Конкретно по конструкции в Вашем вопросе: в C++ это исключение поймать нельзя, для этого придётся использовать платформо-зависимое API, т.к. деление на 0 это исключение(trap) процессора. Если же говорить в общем, то в C++ есть вот такие базовые классы, которые можно либо использовать непосредственно, либо наследоваться от них и уже производить свои классы-исключения, т.е. в этом плане, отличия от Java минимальны. Но наследоваться вовсе не обязательно — любой тип может быть использован в качестве исключения, т.е. нет никаких специальных типов-исключений, есть просто типы, которые можно использовать для создания и перехвата исключений. Также можно добавить, что желательно все классы-исключения в приложении наследовать от одного класса, чтобы можно было разом поймать все исключения в одном месте(например в main). Т.к. все стандартные классы-исключения наследуют std::exception, наследование своих от оного может быть хорошей идеей.

Ответ 2



Начну издалека. Давайте посмотрим на стандартную библиотеку языка. Сразу бросается в глаза, что исключения там почти не используются, особенно если сравнивать с Java, где на каждый чих принято бросать исключения. Например, посмотрим на описание алгоритма std::copy: The ranges shall not overlap in such a way that result points to an element in the range [first,last). Что будет если мы не выполним это условие? Note that invalid arguments cause undefined behavior. А чёрт его знает. Может исключение, может бесконечный цикл, а может форматирование жесткого диска. Короче, undefined behavior. В стандартной библиотеке не принято запрещать программисту выстрелить себе в ногу, если он этого хочет. Что касается вашего примера, он при таком подходе выглядел бы так: double div(double x, double y){ return x/y; } А корректность входных данных пусть остается на совести того, кто эту функцию вызвал. Теперь непосредственно к вашему вопросу. Стандартного исключения при делении на ноль нет. Вот все что есть. Если очень хочется выполнять деление с исключениями то можно написать так class DivisionByZeroException{}; double div(double x, double y){ if(y == 0){ throw DivisionByZeroException(); } return x/y; } И потом использовать эту функцию. Однако настоятельно вам не рекомендую это делать. От исключений в С++ больше проблем чем пользы. Они медленные, исключения в конструкторах ведут к утечкам памяти, исключения в деструкторах ведут к неопределенному поведению, исключения в методах со спецификатором noexcept ведут к аварийному завершению программы, исключения во время обработки исключений также ведут к аварийному завершению программы.

Комментариев нет:

Отправить комментарий