Стефан Дэвис - С++ для чайников .
- Название:С++ для чайников .
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс. Компьютерное издательство Диалектика
- Год:2007
- Город:Москва
- ISBN:0-7645-6852-3, 978-5-8459-0723-3
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стефан Дэвис - С++ для чайников . краткое содержание
1
empty-line
4
С++ для чайников . - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
using namespace std ;
class Obj
{
public :
Obj( char c )
{
label = c ;
cout << "Конструирование объекта " << label << endl ;
}
~Obj ( )
{
cout << "Деструкция объекта " << label << endl ;
}
protected :
char label ;
} ;
void f1( ) ;
void f2( ) ;
int f3( )
{
Obj a( 'a' ) ;
try
{
_________________
293 стр. Глава 25. Обработка ошибок и исключения
Obj b( 'b' ) ;
f1( ) ;
}
catch( float f )
{
cout << "Перехват float" << endl ;
}
catch( int i )
{
cout << "Перехват int" << endl ;
}
catch ( ... )
{
cout << string( "Обобщённое исключение" ) << endl ;
}
return 0;
}
int main( int nNumberofArgs , char* pszArgs[ ] )
{
/* печать кириллицы, если Вы не установите программки gccrus.exe и g++rus.exe */
setlocale ( LC_ALL , ".1251" ) ;
f3( ) ;
/* Пауза для того, чтобы посмотреть на результат работы программы */
system( "PAUSE" ) ; return 0 ;
}
void f1( )
{
try
{
Obj c( 'c' ) ;
f2( ) ;
}
catch( string msg )
{
cout << "Перехват строки" << endl ;
}
}
void f2( )
{
Obj d( 'd' ) ;
throw 10 ;
}
В результате работы этой программы на экран будет выведен следующий текст:
Конструирование объекта а
Конструирование объекта b
Конструирование объекта с
Конструирование объекта d
Деструкция объекта d
Деструкция объекта с
Деструкция объекта b
Перехват int
Деструкция объекта а
Press any key to continue...
_________________
294 стр. Часть 5. Полезные особенности
Как видите, прежде чем в функции f2( ) происходит исключение int , конструируются четыре объекта — а , b , с и d . Поскольку в f2( ) блок try не определён, С++ разворачивает стек вызовов функций, что приводит к ликвидации объекта d при разворачивании стека f2( ) . В функции f1( ) определён блок try , но его блок catch воспринимает только char* , что не совпадает с брошенным объектом int . Поэтому С++ продолжает просмотр, что приводит к разворачиванию стека функции f1( ) ( при этом ликвидируется объект с ).
В функции f3( ) С++ находит ещё один блок try . Выход из этого блока приводит к выходу из области видимости объекта и b . Первый за блоком try блок catch принимает float , что вновь не совпадает с нашим int , поэтому пропускается и этот блок. Однако следующий блок catch наконец-то воспринимает int , и управление переходит к нему. Последний блок catch , который воспринимает любой объект, пропускается, поскольку необходимый блок catch уже найден и исключение обработано.
►Так что же мы будем бросать?...295
За ключевым словом throw следует выражение, которое создаёт объект некоторого типа. В приведённых здесь примерах мы генерировали переменные типа int , но на самом деле ключевое слово throw работает с любым типом объекта. Это значит, что вы можете "бросать" любое количество информации. Рассмотрим приведённое ниже определение класса.
//
/* CustomExceptionClass — демонстрация исключений */
/* при использовании факториала */
#include
#include
#include
#include
using namespace std ;
/* Exception — обобщённый класс исключения */
class Exception
{
public :
Exception( char* pMsg , int n , char* pFile , int nLine )
: msg( pMsg ) , errorValue( n ) , file( pFile ) , lineNum( nLine )
{ }
virtual string display( )
{
ostringstream out ;
out << "Ошибка <" << msg
<< " - значение равно " << errorValue
<< ">\n" ;
out << "@" << file << "-" << lineNum << endl ;
return out.str( ) ;
}
protected :
/* Сообщение об ошибке */
string msg ;
int errorValue ;
/* Имя файла и номер строки, где произошла ошибка */
string file ;
_________________
295 стр. Глава 25. Обработка ошибок и исключения
int lineNum ;
} ;
/* factorial — вычисление факториала */
int factorial( int n )
{
/* Функция не обрабатывает отрицательные значения аргумента */
if ( n < 0 )
{
throw Exception( "Аргумент факториала отрицателен" ,
n , __FILE__ , __LINE__ ) ;
}
/* Вычисляем факториал */
int accum = 1 ;
while ( n > 0 )
{
accum *= n ;
n-- ;
}
return accum ;
}
int main( int nNumberofArgs , char* pszArgs[ ] )
{
/* печать кириллицы, если Вы не установите программки gccrus.exe и g++rus.exe */
setlocale ( LC_ALL , ".1251" ) ;
try
{
/* Этот код работает корректно */
cout << "3! = " << factorial( 3 ) << endl ;
/* Здесь генерируется исключение */
cout << "Factorial of -1 is " << factorial( -1 ) << endl ;
/* Этот код остаётся невыполненным */
cout << "Factorial of 5 is " << factorial( 5 ) << endl ;
}
/* Перехват исключения */
catch( Exception e )
{
cout << "Ошибка: \n" << e.display( ) << endl ;
}
catch ( ... )
{
cout << "Неизвестное исключение" << endl ;
}
/* Пауза для того, чтобы посмотреть на результат работы программы */
system( "PAUSE" ) ; return 0 ;
}
Программа выглядит практически идентичной программе вычисления факториала, приведённой в начале главы. Отличие заключается в том, что здесь для генерации исключения применяется пользовательский класс Exception , который содержит существенно большее количество информации о происшедшей ошибке: сообщение об ошибке, неверный аргумент и точное место, где произошла ошибка.
_________________
296 стр. Часть 5. Полезные особенности
«Встроенные макроопределения _FILE_ и _LINE_ представляют собой имя исходного файла и текущую строку в нём.»
[ Советы ]
Перехватчик исключения использует функцию-член display( ) для вывода сообщения об ошибке. Вывод программы выглядит следующим образом.
3! = 6
Ошибка:
Ошибка <���Аргумент факториала отрицателен — значение равно -1> @С:/Documents/Dial/CppDummy/CustomExceptionClass.срр-46
Press any key to continue...
Класс Exception представляет собой базовый класс для сообщений об ошибках. Вы можете наследовать его и получить класс, который обеспечит более детальную информацию об ошибке. Например, я могу определить класс InvalidArgumentException , который в дополнение к прочему хранит значение неверного аргумента.
Читать дальшеИнтервал:
Закладка: