Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > Деструктор не изменяет состояние потока |
Автор: Nitro89 8.1.2006, 19:43 | ||
Вообщем, пытаясь выполнить упражнение Бьерна Страуструпа, я написал такой код.
И почему в результате выполнения программы, я увидел только две строчки, а не три, т.е. я увидел только "Initialization." и "Work.". Куда третья делась, ведь деструктор класса A полюбому вызывается. Может, std::cout уничтожается до того, как уничтожится a? Объясните пожалуйста. |
Автор: TIGERоX 8.1.2006, 20:05 |
пройдитесь дебугером все нормально деструктор вызывается при выходе объекта за предел видимости если вы поставил например getch перед return ток конечно в консоли ничего не увидите потомучто она уже спрячется перед тем как вызывется деструктор ![]() |
Автор: chipset 8.1.2006, 21:55 |
Компилятор? |
Автор: Mephistopheles 9.1.2006, 10:29 |
По-моему переменную типа A надо объявить в функции main. |
Автор: chipset 9.1.2006, 11:00 |
Это глобальная переменная а вот кажеться компилятор я узнаю -- BCB ![]() |
Автор: threef 9.1.2006, 21:31 | ||||
добавь std::cout.flush(); Ну уж очень навороченный cout. Он такой оптимизированный ! Лучше бы setlocale к нему прикрутили ![]() |
Автор: Hearse 9.1.2006, 22:05 | ||
Прикол в том, что код инициализации/завершения вызывает CRT, посему вызов деструктора A происходит после того, как функция main вернет управление.
Вот такой код покажет все как ты хотел увидеть. |
Автор: blackofe 9.1.2006, 22:58 | ||||||
Hearse в main() можно и без дополнительных скобок обойтись. вот так тоже будет работать:
а вот с изначальным кодом вопрос интересный. у меня (vc++ 7.1.3088) такой код
выдал
так что, мне кажется, что в подобном случае порядок уничтожения глобальных объектов неопределен. и разные компилеры это могут делать по-разному. а что в данном случает "глобальнее" - А или cout - я бы не взялся решить ![]() |
Автор: Void 9.1.2006, 23:06 | ||
Здрасьте. А imbue что такое? |
Автор: Hearse 9.1.2006, 23:22 |
blackofe Момент вызова завершающего кода CRT не определяется стандартом, например в Mingw/GCC 3.4.2 выводится только две строчки. Об'являя же 'а' в блоке {} можно быть уверенным, что деструктор вызовется до завершения main(). |
Автор: blackofe 10.1.2006, 01:04 | ||||||||||||
читаем стандарт: 3.6.1.4 Calling the function void exit(int); declared in <cstdlib> (18.3) terminates the program without leaving the current block and hence without destroying any objects with automatic storage duration (12.4). If exit is called to end a program during the destruction of an object with static storage duration, the program has undefined behavior. 3.6.1.5 A return statement in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling exit with the return value as the argument. If control reaches the end of main without encountering a return statement, the effect is that of executing return 0; так что, вполне в соответствии со стандартом вот такой код
должен вывести
а вот такой
должен вывести:
и, кстати говоря, VC++ 7.1 именно так и работает. и нигде в стандарте не написано, что выход из функции main является implementation-defined. ну, а Mingw/GCC 3.4.2 с его нестрогим следованием стандарту придется засунуть.. куда-нибудь.. ;) можно сказать больше. вот такой код
также выведет
и опять таки в соответствии со стандартом (последнее предложение 3.6.1.5). |
Автор: Hearse 10.1.2006, 01:23 | ||
blackofe Сорри, проглядел - GCC сразу закрывает консоль , просто мне думалось, что он разрушает консоль после return, и не дает вывести "Destroing" такой код все прекрасно показывает
З.Ы. Про станарт и CRT я имел в виду что не определяется порядок разрушение консоли-разрушение об'ектов. |
Автор: threef 10.1.2006, 16:42 | ||||||
blackofe С твоими обьяснениями завершения функции main никак не вяжется простейший пример
Обьект 'a' преспокойненько разрушается, так что exit() тут ни при чем. И CRT нормально продолжает отрабатывать(stdout существует). Все дело в cout, если проверить, то его состояние good() становится вовсе не good: ~A() {printf("Destroing %d\n",std::cout.good());} голобальные обьекты создаются ДО main, разрушаются после, и даже использование внутри main exit() не меняет ситуации
результат -
|
Автор: blackofe 10.1.2006, 21:26 | ||||
threef почему же не вяжется? мы с Hearse'ом обсуждали, нужны ли внутри функции main скобки, чтобы быть уверенным, что деструктор объекта, объявленного внутри функции main, нормально отработает по завершению работы. и мы узнали из стандарта, что все произойдет вполне миленько, если пользоваться return'ом, и нужно быть осторожным при использовании exit(). а у тебя объект a объявлен глобально. и убиваться он будет вместе с другими глобальными объектами. порядок же убития глобальных объектов не оговорен стандартом:
и что умрет раньше - объект a или cout - никто не гарантирует. если программа, откомпиленная твоим конкретнымм компилятором, вывела строку
то это лишь говорит о том, что твой компилер расставил приоритеты именно в таком порядке. и это не значит, что другой компилятор поступит так же. поэтому я бы на это особо не расчитывал. прошу поправить меня, если я чего напутал или понял неправильно. |