Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
21 ошибка прогр... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Имитационное мо... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Реклама
Сейчас на сайте
Гостей: 20
На сайте нет зарегистрированных пользователей

Пользователей: 13,372
новичок: vausoz
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Медиа плейер на Delphi + Пояснительная записка
Метод половинного деления для нахождения корня уровнения на Turbo Pascal...
Движение шарика в эллиптическои параболоиде на Delphi [OpenGL] + Блок схемы

Исключения и деструкторы
Теперь разберемся с тем, как и в каком порядке вызываются деструкторы при генерации исключения. Для этого, во-первых, добавим в деструктор класса ТАггау вывод сообщения, чтобы видеть вызов деструктора:
ТАггау::-TArray()
{ cout << "Destuctor" << endl; delete[]data; data = 6;
}:



Аналогично модифицируем конструктор копирования, чтобы видеть на экране входы в конструктор.
Напишем несколько функций, последовательно вызывающих друг друга. В каждой функции создадим «умный» массив с помощью конструктора копирования (чтобы конструктор не вызывался при передаче параметров, будем передавать их по константной ссылке). В самой «внутренней» функции сгенерируем исключение. И наконец, в главной программе будем перехватывать и обрабатывать возникающие исключения (листинг 7.12).

Листинг 7.12. Проверка «раскрутки» стека
ТАггау f2 (const ТАггау &t)
{ cout << "function f2" << endl;
TArray r(t);
cout << r << endl;
throw TArray::bad_Index();
return r;
}
TArray fl (const TArray &t)
{ cout << "function fl" << endl;
TArray R[] = { t, t, t };
cout << R[0] << endl;
cout << R[l] << endl;
cout << R[2] << endl;
TArray r = f2(t);
return г;.
}
TArray f(const TArray& a)
// самая "внутренняя" функция
// отслеживаем вход
// конструируем массив
// выполняется
// генерация исключения
// не выполняется!!!!!

// отслеживаем вход
// создается три массива
// выполняется
// выполняется
// выполняется
// г не создается - не "успевает"
// не выполняется!!!!!

продолжение &

Листинг 7.12 (продолжение)
{ cout << "function f" << endl; // отслеживаем вход
ТАггау t = fl(a); // t не создается - не "успевает"
cout << t << endl; // не выполняется!!!!
return t; //не выполняется!!!!
}
int main()
{ double a[5] = {1.2,3,4,5};
TArray B(a, a+(sizeof(a)/sizeof(double)));
try { f(B); // контролируем
}
// секции-ловушки
catch(TArray::bad_Index) {cout <<"Индекс плохой!"<< endl;} catch(TArray::bad_Range) {cout <<"Диапазон плохой!"<< endl;} catch(TArray::bad_Size) {cout <<"Размер плохой!"<< endl;}
// непредвиденное исключение
catch(...){cout <<"Exceptions!"<< endl;} return 0;
}



При запуске программы мы увидим на экране следующее:
function f function fl



Конструктор копирования! Конструктор копирования! Конструктор копирования! 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 function f2
Конструктор копирования!
1 2 3 4 5
Destuctor
Destuctor
Destuctor
Destuctor
Индекс плохой!



Последовательность действий в этом примере следующая:
1. В главной функции объявляется массив а и из него конструируется «умный» массив В.
2. Выполняется вход в контролируемый блок и вызывается функция f (), которой передается параметр — «умный» массив В.
3. В функции первым выполняется оператор вывода, и на экране появляется первая строка:
function f
4. Во второй строке функции f () прописано объявление «умного» массива t, однако до вызова конструктора дело не доходит, так как вызывается функция f 1 ().
5. Первый оператор функции f 1() выводит на экран строку:
function fl
6. В функции f 1 () создается массив R из трех «умных» массивов, и конструктор копирования вызывается трижды.
7. Выполняется вывод на экран трех элементов-массивов.
8. Хотя объявление «умного» массива г прописано, вызова конструктора не происходит, так как вызывается функция f 2 ().
9. Функция f 2 () выводит на экран строку:
function f2
Создается локальный «умный» массив г, конструктор копирования отрабатывает один раз.
10. Содержимое массива г выводится на экран.
11. Генерируется исключение bad_Index.
К этому моменту у нас создаются один локальный массив в функции f 2 () и массив R из трех массивов в функции f 1 (), которые находятся в стеке. При генерации исключения деструктор вызывается четыре раза, что мы и наблюдаем на экране. После этого происходит переход в секцию-ловушку и выводится строка «Плохой индекс». Затем выполняется выход из секции в тело главной функции и программа завершает работу.
Теперь распределим обработку исключения по разным функциям. Добавим в функцию f 1 () контролирующий блок и идентифицируем вывод в секции-ловушке в главной программе (листинг 7.13).

Листинг 7.13. Распределенная обработка исключения
TArray fl (const TArray &t)
{ cout << "function fl" << endl;
TArray R[] = { t, t, t };
cout << R[0] << endl;
cout << R[l] << endl;
cout << R[2] << endl;
try { // контролируем вызов f2
TArray r = f2(t); // локальный объект
return r; // нормальное завершение
}
catch(TArray::bad_Index)
{ cout <<"fl. Плохой индекс!"<< endl;
throw; // повторная генерация исключения
};
}
int main()
{ double a[5] = {1,2,3,4,5};
TArray B(a, a+(sizeof(a)/sizeof(double)));
try { f(B); // контролируем
}
// секции-ловушки
catch(TArray::bad_Index) {cout <<"Main. Индекс плохой!"<< endl;} catch(TArray::bad_Range) {cout <<"Диапазон плохой!"<< endl;} catch(TArray::bad_Size) {cout <<"Размер плохой!"<< endl;}



Листинг 7.13 (продолжение)
11 непредвиденное исключение
catch(...){cout <<"Exceptions!"<< endl;} return 0;
}
Остальные функции оставим без изменения. При запуске этой программы на экране появится следующее:
function f function fl
Конструктор копирования! Конструктор копирования! Конструктор копирования! 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 function f2
Конструктор копирования!
12 3 4 5 //до этого момента поведение повторяется
Destuctor // при выходе из f2
fl. Плохой индекс1 // секция-ловушка в функции fl
Destuctor // выход из fl
Destuctor
Destuctor
Main. Плохой индекс! // секция-ловушка в main()



Поведение программы повторяется до генерации исключения. Выполнение оператора throw приводит к выходу из функции f2(), при этом вызывается деструктор. В вызывающей функции обнаруживается секция-ловушка нужного типа, которая и выполняется. В ее конце срабатывает оператор повторной генерации исключения. Происходит выход из функции f 1 () — при этом трижды вызываются деструктор для уничтожения элементов массива R. В вызывающей функции — а это уже главная функция main О — ищется секция-ловушка нужного типа. Она у нас в программе есть, и мы наблюдаем ее работу в последней строке, выведенной на экран.
В связи с тем, что деструктор вызывается для уничтожения локальных объектов при генерации любого исключения, сам деструктор генерировать исключения не должен (но, вообще говоря, может). Как указывает Герб Саттер в [21], «все деструкторы должны разрабатываться так, как если бы они имели спецификацию исключения throw(), то есть ни одному исключению не должно быть позволено выйти за пределы деструктора». Если же это произойдет, то программа завершается аварийно. Это означает, что исключения, возникающие в деструкторе, должны быть перехвачены и обработаны там же.
У программистов часто заканчиваются чернила в катриджах, которые найти можно тут - http://bigcmyk.ru/shop/product/006R01517-toner-kartridzh-chernyj-26k-xerox-wc-75xx-78xx.
Деструкторы наших классов ТАггау и TDeque исключений не генерируют — они просто возвращают память. Как мы знаем, по стандарту (см. п. 18.4 в [1]) функции возврата памяти имеют прототипы:
void operator delete (void *) throw(); void operator delete [](void *) throw();



Пустая спецификация исключений показывает, что стандарт гарантирует отсутствие исключений при возврате памяти.
Опубликовал Kest November 11 2013 01:02:00 · 0 Комментариев · 3541 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
Язык программиров...
FatScrollbar
Allsubmitter 4.7 ...
AntiRus
С# для профессион...
Киллер окон
Изучаем Ассемблер
Фильтры изображений
Drag&Drop
Exe in exe
XPATComponents
SMLPack v1.0
FreeSMS v1.3.1
MP3 Архив v.2.0
Averaging [Исходн...
Delphi 2005 для W...
Comdrv
DateEdit
Применение жадног...
Fig [Исходник на ...

Топ загрузок
Приложение Клие... 100774
Delphi 7 Enterp... 97839
Converter AMR<-... 20268
GPSS World Stud... 17014
Borland C++Buil... 14193
Borland Delphi ... 10293
Turbo Pascal fo... 7374
Калькулятор [Ис... 5984
Visual Studio 2... 5207
Microsoft SQL S... 3661
Случайные статьи
Тестирование
Протокол RSVP
12.2. Одно из решений
Согласование актив...
удаленного офиса с...
ENTER (ВОЙТИ В ПАМ...
Выбираем значение ...
Как в выбранной яч...
Эксперименты с при...
Псевдонимы адресов
Английская гласная...
Учитесь у плотников
Старший и младший ...
atomic(X)
Потери на стыках в...
Итерация списка - ...
3.1 ЦЕЛЬ: ХРАНЕНИЕ...
Символы, используе...
Максимальная нагля...
Игровые автоматы с...
Работа с базами да...
Далее перечислены ...
Как был взломан AL...
Исследование прост...
Ограничения, связа...
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?