Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 165, средняя оценка - 4.64
xKirillx
1 / 1 / 0
Регистрация: 01.03.2011
Сообщений: 11
#1

Try..catch..Throw - C++

05.07.2011, 23:05. Просмотров 23115. Ответов 13
Метки нет (Все метки)

Объясните пожалуйста разницу. Желательно с примерами, например деление на ноль, ну или чтобы было сразу несколько исключений. Расскажите пожалуйста про библиотеку exception. Заранее спасибо
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.07.2011, 23:05
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Try..catch..Throw (C++):

try, catch, throw - C++
пишу класс namespace mystd { const uint32_t def_size = 1 << 20; //default memory container template<typename T> ...

try-throw-catch - C++
#include <iostream> #include <math.h> using namespace std; class Drob { public: int obchuslennia (int a, int...

Try, catch, throw - C++
Подскажите, как с помощью try, catch, throw, обработать исключение на вводимый тип данных? Например, допускается только тип int, что...

throw, try, catch - C++
Пожалуйста, помогите разобраться в том, что это такое, и как его правильно использовать. Где можно об этом почитать? P.S. только начал...

Try Throw Catch пример - C++
Как-то не особо много инфы нарыл по данной теме... Может у кого есть какие уже реализованные примеры?

Try,catch,throw,OVERFLOW! - C++
Добрый вечер! И СНОВА с вами try..catch...:p Я очень долго пытался понять try-catch сам, читал везде, где только можно(ссылки давать...

13
nameless
Эксперт С++
334 / 298 / 14
Регистрация: 16.06.2009
Сообщений: 486
05.07.2011, 23:19 #2
Цитата Сообщение от xKirillx Посмотреть сообщение
Объясните пожалуйста разницу.
Разницу между чем и чем?

Добавлено через 4 минуты
Цитата Сообщение от xKirillx Посмотреть сообщение
Расскажите пожалуйста про библиотеку exception
http://www.cplusplus.com/reference/std/exception/

Там же и куча примеров..
0
xKirillx
1 / 1 / 0
Регистрация: 01.03.2011
Сообщений: 11
05.07.2011, 23:20  [ТС] #3
Спасибо, перепишу

Объясните пожалуйста как ловить исключения с помощью этих 3х слов, и для чего каждое используется. Желательно с примерами, например деление на ноль, ну или чтобы было сразу несколько исключений. Расскажите пожалуйста про библиотеку exception. Заранее спасибо
0
Jupiter
Каратель
Эксперт С++
6559 / 3980 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
05.07.2011, 23:26 #4
а что мешает открыть:
1-е гугл
2-е учебник
да и к тому же по ссылке, которую дал nameless вполне доступные примеры и описание std::exception
0
xKirillx
1 / 1 / 0
Регистрация: 01.03.2011
Сообщений: 11
05.07.2011, 23:29  [ТС] #5
Пишу сюда первый раз с марта, упорно решаю задачи на "ура", гуглю и читаю учебники, ну вот не понимаю я, решил обратиться сюда. Сессии вроде как закончились, так что спрашиваю для себя. Если нетрудно объясните кто-нибудь на пальцах.
1
Jupiter
Каратель
Эксперт С++
6559 / 3980 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
05.07.2011, 23:42 #6
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
 
int main () 
{
    try
    {
        int num = 10, denum = 0;
        if(denum == 0)
            throw "Division by zero";
        int result = num / denum;
        std::cout << result;
    }
    catch(const char* msg)
    {
        std::cout << msg;
    }
    std::getchar();
    return 0;
}
Добавлено через 36 секунд
а теперь конкретные вопросы?
2
xKirillx
1 / 1 / 0
Регистрация: 01.03.2011
Сообщений: 11
05.07.2011, 23:49  [ТС] #7
1. Если например у в программе нельзя делить не только на ноль но и еще например на 11,12,13,14,15, то я должен создавать 6 if, ну или например switch?
2. Есть ли какой-то универсальный обработчик, например я бы хотел отлавливать деление на 0, и например все остальные ошибки.
3. никак не могу понять catch(что тут пишется), идентификатор по которому я ловлю ошибку?
4. ошибки определенного типа отлавливаются только в блоке try? Если я пишу программу, и хочу чтобы при возникновении непредвиденной для меня ошибки появлялось сообщение, возникла непредвиденная ошибка обратитесь к администратору.

Спасибо
0
zuq
95 / 95 / 2
Регистрация: 10.04.2011
Сообщений: 256
05.07.2011, 23:53 #8
Цитата Сообщение от xKirillx Посмотреть сообщение
Объясните пожалуйста как ловить исключения с помощью этих 3х слов, и для чего каждое используется.
throw - генерирует исключение. Например
C++
1
throw "error 1";
Исключения можно генерировать только внутри блока try. Тоесть
C++
1
2
3
4
5
6
//.....
try {
         //...
        throw 1;  Правильно, т.к в try блоке
        //..
}
Правильно, т.к исключение в try блоке
C++
1
2
3
// ...
throw 2;
//...
Это будет ошибкой.
catch служит для перехвата исключений. Синтаксис такой catch(Type var) { ... }. type - тип исключениия которое ловит этот блок. var - само исключение.

Вот вроде так Поверхностно - но все же_)

Например - все исключения типа int будут "отправляться" в catch(int) {}
2
OstapBender
584 / 523 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
05.07.2011, 23:57 #9
просто тема не раз обсуждалась уже...

в блоке try ты хочешь проверить фрагмент в котором может возникнуть исключение.
исключение возбуждается с помощью ключевого слова throw.
в каждом из блоков catch можно перехватить по 1 типу данных.
catch(...) перехватывает любые типы. поэтому его рекомендуется ставить в конец для неожиданных ошибок.

обычно удобно выбрасывать не какие то переменные а объекты типа exception ( тут несколько вариантов: можно самому написать класс исключений, можно воспользоваться стандартным классом std::exception или другими производными от него, можно самому написать производный от него...)

также некоторые стандартные функции из std и операторы могут возбуждать исключения которые вообще говоря необходимо проверять.

дурацкий пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
try {
int n;
std::cin >> n;
std::cin.ignore();
switch(n) {
case 0: throw 1;
case 1: throw 1.0;
default: throw 'a';
} catch(int ) {
std::cout << "int";
} catch(double d) {
std::cout << "double " << d ;
} catch(...) {
std::cout << "char";
}
пример со стандартными исключениями:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int *p;
 
while (1) {
try {
p = new int[4096];
} catch(std::bad_alloc e) {
std::cout << e.what() << '\n';
}
 
}
 
...
 
std::vector<int> vec(10,0);
try {
std::cout << vec.at(15);
} catch(std::out_of_range e) {
std::cout << e.what() << '\n';
}
свой простой класс:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class MyException {
std::string exc;
public:
MyException() { exc="unindicated exception"; }
MyException(char* st):exc(st) {}
const std::string what() { return exc; }
};
 
 
...
 
int i=10;
int j=0;
 
try {
 
if (j==0)
throw MyException("division by zero.");
else i/=j;
 
} catch(MyException& e) {
std::cout << e.what() << '\n'; 
}
2
xKirillx
1 / 1 / 0
Регистрация: 01.03.2011
Сообщений: 11
05.07.2011, 23:58  [ТС] #10
Логика такова
try{}
в фигурных скобках место где мы ждем исключения.
throw - мы говорим о том какая ошибка
catch обрабатываем все виды ошибок??
0
zuq
95 / 95 / 2
Регистрация: 10.04.2011
Сообщений: 256
05.07.2011, 23:59 #11
Цитата Сообщение от xKirillx Посмотреть сообщение
catch обрабатываем все виды ошибок??
catch(int){} - обрабатывает int. catch(char) - char и т.д. catch(...){} обрабатывает все исключения
0
ValeryLaptev
Эксперт С++
1042 / 821 / 48
Регистрация: 30.04.2011
Сообщений: 1,659
06.07.2011, 00:01 #12
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Правильные книжки надо читать...
Вот тебе из моей:

Принципы обработки исключений
В С++ исключение — это объект. Хотя обычно говорят об исключительной ситуации в программе, такая точка зрения мало что дает, так как с ситуацией сделать ничего нельзя. Поэтому в С++ при возникновении исключительной ситуации программа должна генерировать объект-исключение. Собственно, сама генерация объекта-исключения и создает исключительную ситуацию. Такой подход очень удобен, так как с объектами, в отличие от ситуации, мы можем много чего делать. Например, объявлять как обычную переменную, передать его как параметр любым из возможных способов или возвратить в качестве результата. Можно объявлять массивы исключений или включать объекты-исключения в качестве полей в другие классы. В дальнейшем мы будем использовать термин «исключение», понимая под этим объект-исключение.

Общая схема обработки исключений такова: в одной части программы, где обнаружена аварийная ситуация, исключение порождается; другая часть программы контролирует возникновение исключения, ловит и обрабатывает его. В С++ есть три зарезервированных слова: try (контролировать), catch (ловить), throw (порождать), — которые и используются для организации процесса обработки исключений.

Генерация исключений
Генерируется исключение оператором throw [1-15.1], который имеет следующий синтаксис
throw выражение_генерации_исключения;
Фраза «выражение_генерации_исключения» на практике означает либо константу, либо переменную некоторого типа. Тип объекта-исключения может быть любым, как встроенным, так и определяемым программистом. Например,
C++
1
2
3
4
throw 7;
throw "Ошибка: деление на ноль!";
throw Message[i];
throw M_PI;
В первом случае объект-исключение — это целая константа, которая может быть условным номером-кодом ошибки. В общем случае этот код ошибки может вычисляться, например
C++
1
throw 3*v-i;
Выражение, конечно, может быть не только целочисленным.
Второй вариант — это символьная константа, которая фактически является сообщением об ошибке. Если все сообщения об ошибках записаны в массиве, например,
C++
1
string Message[326];
то в третьем варианте объект-исключение тоже представляет собой строку — сообщение об ошибке. В последнем примере в качестве объекта используется дробная константа — число.
Программист может и сам определить свой собственный тип объекта-исключения, объявив новый класс, например
C++
1
2
3
4
class NegativeArgument{};
NegativeArgument exeption;
if (x>0) double t = x/sqrt(x);
else throw exeption;
Пустые классы неожиданно пригодились! Однако объявлять переменную совсем не обязательно, можно обойтись и без этого, например
C++
1
throw NegativeArgument();
Здесь в качестве «выражения генерации исключения» мы использовали явный вызов конструктора без аргументов, и это наиболее часто используемая форма генерации исключения.
Объект-исключение может быть и динамическим, например,
C++
1
throw new NegativeArgument();
Однако в этом случае возникает вопрос об уничтожении объекта-исключения и возврате памяти — неизвестно, в каком месте программы это можно сделать. Лучше не создавать себе проблем и не использовать указатели в качестве параметров catch-блоков.

Перехват и обработка исключений
Сгенерировать исключение — это только полдела. Исключение надо перехватить и обработать. Проверка возникновения исключения делается с помощью оператора try, с которым неразрывно связаны одна или несколько секций-ловушек catch. Оператор try объявляет в любом месте программы контролируемый блок, который имеет следующий вид
C++
1
try { /* контролируемый блок */ }
Контролируемый блок, помимо функции контроля, обладает функциями обычного блока: все переменные, объявленные внутри него, являются локальными в этом блоке и не видны вне его.
После try-блока обязательно прописывается один или несколько catch-блоков, которые обычно называют обработчиками исключений. Форма записи секции-ловушки следующая:
C++
1
catch (спецификация_исключения) { /* блок обработки */}
«Спецификация_исключения» может иметь следующие три формы:
(тип имя)
(тип)
(…)
Тип должен быть одним из допустимых типов исключений — либо встроенный, либо определенный программистом . Первый вариант спецификации означает, что объект-исключение передается в блок обработки, чтобы там его как-то использовать, например, для вывода информации в сообщении об ошибке.

ВНИМАНИЕ
При выполнении оператора throw создается временный объект-исключение [1 15.1/3], который и передается в секцию-ловушку.

При этом объект-исключение может передаваться в секцию-ловушку любым способом: по значению, по ссылке или по указателю, например
C++
1
2
3
4
catch (TException e)            // по значению
catch (TException& e)           // по ссылке
catch (const TException& e)     // по константной ссылке
catch (TException *e)           // по по указателю
Однако в отличие от параметров функций, никаких преобразований по умолчанию не производится . Это означает, что если в программе написан заголовок обработчика,
catch (double e) // по значению
то попадают в эту секцию только те исключения, тип выражения исключений которых совпадает с double. Оператор
C++
1
throw 1
генерирует исключение целого типа, поэтому будет обрабатываться секцией-ловушкой с заголовком, в которой прописан целый тип исключения, например
C++
1
catch (int e)           // по значению
или
C++
1
catch (int)             // без передачи информации в секцию-ловушку
Это легко проверить, выполнив следующую простую тестирующую программу:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{   try { throw 1;                          // генерация исключения
        }
    catch(unsigned int)
        { cout << "unsigned integer" << endl;
        }
    catch(int)                              // перехватывается здесь
        { cout << "integer" << endl;
        }
    catch(double)
        { cout << "double" << endl;
        }
    return 0;
}
На экране появится слово integer, так как константа 1 по умолчанию имеет тип int.
Первые две формы из приведенных выше спецификаций исключения предназначены для обработки конкретного типа исключений. Если же на месте спецификации исключения написано многоточие (как в функциях с переменным числом параметров), то такой обработчик перехватывает все исключения.

Работа конструкции try-catch напоминает работу оператора switch. Секции-ловушки похожи на альтернативы case, а catch-блок с многоточием соответствует альтернативе default оператора-переключателя. Если в try-блоке возникает исключение, то начинается сравнение типа сгенерированного исключения и типов параметров в секциях-ловушках. Выполняется тот catch-блок, тип параметра которого совпал с типом исключения. Если такого типа не найдено, но есть catch с многоточием, то выполняется его блок. Если же такого блока в текущем списке обработчиков не обнаруживается, то ищется другой список обработчиков в вызывающей функции. Этот поиск продолжается вплоть до функции main(). Если же и там не обнаружится нужного catch-блока, то вызывается стандартная функция завершения terminate() [1-15.5.1], которая вызывает функцию abort().

Таким образом, очень важен порядок записи секций-ловушек после контролируемого блока. Если в качестве первого обработчика после try-блока задан catch-блок с параметром-многоточием, то такой обработчик будет обрабатывать все возникающие исключения — до остальных секций-ловушек дело просто не дойдет. Поэтому усвойте следующее простое правило: всегда задавать catch-блок с параметром-многоточием последним. Секция-ловушка с многоточием — это крайняя мера: если уж мы в нее попали, то в программе произошло что-то совсем не предусмотренное. Поэтому в такой секции обычно выводят сообщение о непредвиденном исключении и завершают работу программы.
Выход из секции-ловушки выполняется одним из следующих способов:
1. выполнились все операторы обработчика — происходит неявный переход к оператору, расположенному после конструкции try-catch;
2. в обработчике выполняется оператор goto ; разрешается выполнять переход на любой оператор вне конструкции try-catch; внутрь контролируемого блока и в другую секцию-ловушку переход запрещен;
3. в обработчике выполняется оператор return; происходит нормальный выход из функции;
4. в секции ловушке выполняется оператор throw;
5. в обработчике генерируется другое исключение.
Рассмотрим подробнее два последние способа выхода. Оператор throw без выражения генерации исключения генерирует повторное исключение того же типа. Такая форма оператора допустима только внутри секции-ловушки.

ПРИМЕЧАНИЕ
Выполнение этого оператора вне секции-ловушки приведет к немедленному аварийному завершению программы [1-15.1/8].

Однако это не приводит к рекурсивному входу в тот же обработчик — ищется другой обработчик выше по иерархии вложенности. Аналогично, при генерации в секции-ловушке исключения другого типа ищется его обработчик выше по иерархии вложенности. Если нужного catch-блока не обнаруживается, то программа аварийно завершается. Таким образом, мы имеем возможность «распределить» обработку исключения по разным частям программы.
Выход из обработчика по исключению может привести к выходу из функции. Очень важно, что стандарт [1-15.2/1] гарантирует в этом случае вызов деструкторов для уничтожения локальных объектов. Этот процесс уничтожения локальных объектов при выходе по исключению называется «раскруткой» (unwinding) стека. Нужно подчеркнуть, что раскрутка стека выполняется только для локальных объектов — для динамических объектов, созданных операцией new, деструкторы автоматически не вызываются. Маленький пример продемонстрирует эту ситуацию:
C++
1
2
3
4
5
6
7
8
9
10
void f1(void)
{ //…
  MyObject t;
  throw MyException();
}
void f2(void)
{ //…
  MyObject t = new MyObject();
  throw MyException();
}
Генерация исключения в функции f1() приведет к вызову деструктора для уничтожения локального объекта t. При генерации исключения в функции f2() деструктор класса MyObject не вызывается, так как объект создан в динамической памяти. Более того, уничтожается локальный указатель, и это приводит к утечке памяти. Обычно эта проблема решается с помощью интеллектуальных указателей [20, 21, 24, 25, 28].

ПРИМЕЧАНИЕ
В стандартной библиотеке STL реализован один из видов интеллектуальных указателей auto_ptr.

После выполнения операторов catch-блока при отсутствии явных операторов перехода или оператора throw выполняются операторы, расположенные после всей конструкции try-catch. Если во время работы в try-блоке не обнаружено исключительной ситуации, то все catch-блоки пропускаются, и программа продолжает выполнение с первого оператора после всех catch.
Блоки try-catch могут быть вложенными, причем как в try-блок, так и в catch-блок:
C++
1
2
3
4
5
6
7
8
9
10
try {   // блок, который может инициировать исключения
    try {   //вложенный блок
    }
    catch(){   }
}
catch (исключение) {    // обработка исключения
    try {   //вложенный блок
    }
    catch(){   }
}
Необходимо отметить, что исключение может быть сгенерировано в одном месте программы, а обработано совершенно в другом.
8
yoghurt92
374 / 345 / 22
Регистрация: 17.05.2012
Сообщений: 1,049
24.01.2013, 19:51 #13
ValeryLaptev, а не подскажите что за учебник?
0
silent_1991
Эксперт С++
4987 / 3044 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
29.01.2013, 12:34 #14
Цитата Сообщение от zuq Посмотреть сообщение
Исключения можно генерировать только внутри блока try.
Ничего подобного. В С++, в отличие от джавы, исключения непроверяемые, т.е. их можно бросать где угодно. Если при расткрутке стека выйдем за контекст функции main - исключение, грубо говоря, поймает стандартный обработчик, который прервёт выполнение программы и выведет дополнительную информацию об исключении (результат вызова метода what на объекте исключения).
0
29.01.2013, 12:34
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.01.2013, 12:34
Привет! Вот еще темы с ответами:

try, throw, catch...обработка исключений - C++
помогите разобраться с обработкой исключений...при вводе пароля больше 10 символов должна быть непредвиденная ошибка, пытаюсь ее поймать,но...

Try throw catch в решении уравнения - C++
Есть уравнение y=1/sqrt(x-3). нужно считать x, пусть он будет целым. а затем с помощью исключений обработать ошибки: 1) ввели...

C++ try catch throw в разных функциях - C++
try и catch находятся в одной функции а throw вызывается из другой. ну MVS выкидывает исключение вместо передачи управления. что делать?...

try catch throw для чего нужны? - C++
Для чего нужны эти операторы? Линканите пожалуйста статью, где доходчиво объяснено их применение, в разных вариантах (например я видел...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru