Навигация
Главная
Поиск
Форум
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
Реклама
Сейчас на сайте
Гостей: 7
На сайте нет зарегистрированных пользователей

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

База данных междугородних телефонных разговоров на Delphi
Расчет обратной матрицы на Delphi + Пояснительная записка
Игра Sokoban на Delphi + Блок схемы

Исключения и деструкторы
Теперь разберемся с тем, как и в каком порядке вызываются деструкторы при генерации исключения. Для этого, во-первых, добавим в деструктор класса ТАггау вывод сообщения, чтобы видеть вызов деструктора:
ТАггау::-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 Комментариев · 3540 Прочтений · Для печати

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


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



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

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

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

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

Пароль



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

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

Случайные загрузки
MicroGPSS Studen ...
Основы Delphi
Игра Car [Исходни...
Панель статистики...
PHP: настольная к...
Программирование ...
AUTOWEB
Trojan [Исходник ...
Text3D
Программа для рис...
AID антивирус
PolyFlow
Упорядоченный дин...
Программирование ...
Панель случайной ...
NotePad Pro [Исхо...
Microsoft Press -...
Adapter (пример D...
Мониторинг сервер...
DCAVI

Топ загрузок
Приложение Клие... 100774
Delphi 7 Enterp... 97838
Converter AMR<-... 20268
GPSS World Stud... 17014
Borland C++Buil... 14192
Borland Delphi ... 10293
Turbo Pascal fo... 7374
Калькулятор [Ис... 5984
Visual Studio 2... 5207
Microsoft SQL S... 3661
Случайные статьи
Использование буф...
Глава 11. Как э...
Сигнализации новог...
Включение датчика NFC
Установка подсветк...
этого службу Telne...
Сообщения протокол...
Этап 9: выполните ...
Использование ICQ
Анализ продвижения...
• Раскрытие циклов...
Создание очередей
Главное меню
Отдых и развлечения
МОДЕЛЬ С АКТИВНОЙ ...
Советы как бесплат...
Антисептик для дерева
ПМ Казино с бонусо...
каталогов полномоч...
Например, во время...
Игра в планирование
Можно ли доверять ...
Особенности органи...
east.microsoft.
Платформа Mac
Статистика



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


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