Навигация
Главная
Поиск
Форум
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
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Модуль Forms 65535
ТЕХНОЛОГИИ ДОСТ... 64200
Имитационное мо... 58790
Реклама
Сейчас на сайте
Гостей: 4
На сайте нет зарегистрированных пользователей

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

База данных - словарь терминов на Delphi + Пояснительная записка
Обработка задач на ЭВМ на GPSS + Пояснительная записка
Моделирование автомойки на GPSS + Отчет + Блок схемы

Реклама



Подписывайся на YouTube канал о программировании, что бы не пропустить новые видео!

ПОДПИСЫВАЙСЯ на канал о программировании
Исключения и деструкторы
Теперь разберемся с тем, как и в каком порядке вызываются деструкторы при генерации исключения. Для этого, во-первых, добавим в деструктор класса ТАггау вывод сообщения, чтобы видеть вызов деструктора:
ТАггау::-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 05:02:00 · 0 Комментариев · 2544 Прочтений · Для печати

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


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



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

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

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

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

Пароль



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

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

Случайные загрузки
Экспорт базы данн...
DAlarm
Киллер окон
Использование Lis...
Adapter (пример D...
index.php + мод ...
Шейдеры в Delphi
Основы программир...
Игра PackMan
Task Shedule
Просмотр коммент...
MPTools
iChat v.7.0 Final...
Socoban
Flud Vkontakte.ru
Введение в станда...
Панель Календарь
Язык программиров...
WordReport
Cтатьи Королевств...

Топ загрузок
Приложение Клие... 100498
Delphi 7 Enterp... 88657
Converter AMR<-... 20084
GPSS World Stud... 14014
Borland C++Buil... 12273
Borland Delphi ... 8764
Turbo Pascal fo... 7062
Visual Studio 2... 5007
Калькулятор [Ис... 4988
FreeSMS v1.3.1 3547
Случайные статьи
Пятнашки на Strawb...
Модули таблиц
Представления дере...
Базис I, B, C, S
Интерфейс модели в...
Интерфейс между ко...
HTPC на базе Windows
Работа с хэшами в ...
• Модернизированны...
Хакинг
Виды роботов Яндекса
Жизнь после мигра...
Построение списка
Установление свойс...
Использование спец...
Немного о прерываниях
Организация информ...
Гостевая книга на PHP
будет проводиться ...
Добавление кода дл...
Магнитные выключатели
DSClient позволяет...
Переписать элемент...
Виртуализация внеш...
Выработка решенияС...
Статистика



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


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