![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
Nitro89 |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 26 Регистрация: 18.3.2005 Репутация: нет Всего: нет |
Вообщем, пытаясь выполнить упражнение Бьерна Страуструпа, я написал такой код.
И почему в результате выполнения программы, я увидел только две строчки, а не три, т.е. я увидел только "Initialization." и "Work.". Куда третья делась, ведь деструктор класса A полюбому вызывается. Может, std::cout уничтожается до того, как уничтожится a? Объясните пожалуйста. |
|||
|
||||
TIGERоX |
|
|||
начинающий... ![]() Профиль Группа: Участник Сообщений: 59 Регистрация: 7.9.2005 Репутация: нет Всего: 1 |
пройдитесь дебугером все нормально деструктор вызывается при выходе объекта за предел видимости если вы поставил например getch перед return ток конечно в консоли ничего не увидите потомучто она уже спрячется перед тем как вызывется деструктор
![]() Это сообщение отредактировал(а) TIGERоX - 8.1.2006, 20:08 |
|||
|
||||
chipset |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4071 Регистрация: 11.1.2003 Где: Seattle, US Репутация: 27 Всего: 164 |
Компилятор?
--------------------
|
|||
|
||||
Mephistopheles |
|
|||
![]() Бегущий от света ![]() Профиль Группа: Участник Сообщений: 146 Регистрация: 15.11.2005 Где: Где нет света Репутация: нет Всего: 6 |
По-моему переменную типа A надо объявить в функции main.
--------------------
Ангелы и бесы кружат надо мной.Ангел или бес - делай выбор свой.Вспыхнуть огнём; вознестись до небесДелай выбор свой: ангел или бес?© Mephistopheles, бегущий от света. |
|||
|
||||
chipset |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4071 Регистрация: 11.1.2003 Где: Seattle, US Репутация: 27 Всего: 164 |
Это глобальная переменная а вот кажеться компилятор я узнаю -- BCB
![]() --------------------
|
|||
|
||||
Nitro89 |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 26 Регистрация: 18.3.2005 Репутация: нет Всего: нет |
||||
|
||||
threef |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 375 Регистрация: 27.10.2005 Где: Запорожье Репутация: 9 Всего: 10 |
добавь std::cout.flush(); Ну уж очень навороченный cout. Он такой оптимизированный ! Лучше бы setlocale к нему прикрутили ![]() Это сообщение отредактировал(а) threef - 9.1.2006, 21:36 |
||||
|
|||||
Hearse |
|
|||
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 13.1.2004 Репутация: нет Всего: нет |
Прикол в том, что код инициализации/завершения вызывает CRT, посему вызов деструктора A происходит после того, как функция main вернет управление.
Вот такой код покажет все как ты хотел увидеть. Это сообщение отредактировал(а) Hearse - 9.1.2006, 23:30 |
|||
|
||||
blackofe |
|
||||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 173 Регистрация: 29.11.2005 Репутация: 4 Всего: 4 |
Hearse
в main() можно и без дополнительных скобок обойтись. вот так тоже будет работать:
а вот с изначальным кодом вопрос интересный. у меня (vc++ 7.1.3088) такой код
выдал
так что, мне кажется, что в подобном случае порядок уничтожения глобальных объектов неопределен. и разные компилеры это могут делать по-разному. а что в данном случает "глобальнее" - А или cout - я бы не взялся решить ![]() |
||||||
|
|||||||
Void |
|
|||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
-------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
|||
|
||||
Hearse |
|
|||
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 13.1.2004 Репутация: нет Всего: нет |
blackofe Момент вызова завершающего кода CRT не определяется стандартом, например в Mingw/GCC 3.4.2 выводится только две строчки.
Об'являя же 'а' в блоке {} можно быть уверенным, что деструктор вызовется до завершения main(). Это сообщение отредактировал(а) Hearse - 9.1.2006, 23:24 |
|||
|
||||
blackofe |
|
||||||||||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 173 Регистрация: 29.11.2005 Репутация: 4 Всего: 4 |
читаем стандарт:
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). Это сообщение отредактировал(а) blackofe - 10.1.2006, 01:08 |
||||||||||||
|
|||||||||||||
Hearse |
|
|||
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 13.1.2004 Репутация: нет Всего: нет |
blackofe Сорри, проглядел - GCC сразу закрывает консоль , просто мне думалось, что он разрушает консоль после return, и не дает вывести "Destroing"
такой код все прекрасно показывает
З.Ы. Про станарт и CRT я имел в виду что не определяется порядок разрушение консоли-разрушение об'ектов. Это сообщение отредактировал(а) Hearse - 10.1.2006, 01:32 |
|||
|
||||
threef |
|
||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 375 Регистрация: 27.10.2005 Где: Запорожье Репутация: 9 Всего: 10 |
blackofe
С твоими обьяснениями завершения функции main никак не вяжется простейший пример
Обьект 'a' преспокойненько разрушается, так что exit() тут ни при чем. И CRT нормально продолжает отрабатывать(stdout существует). Все дело в cout, если проверить, то его состояние good() становится вовсе не good: ~A() {printf("Destroing %d\n",std::cout.good());} голобальные обьекты создаются ДО main, разрушаются после, и даже использование внутри main exit() не меняет ситуации
результат -
|
||||||
|
|||||||
blackofe |
|
||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 173 Регистрация: 29.11.2005 Репутация: 4 Всего: 4 |
threef
почему же не вяжется? мы с Hearse'ом обсуждали, нужны ли внутри функции main скобки, чтобы быть уверенным, что деструктор объекта, объявленного внутри функции main, нормально отработает по завершению работы. и мы узнали из стандарта, что все произойдет вполне миленько, если пользоваться return'ом, и нужно быть осторожным при использовании exit(). а у тебя объект a объявлен глобально. и убиваться он будет вместе с другими глобальными объектами. порядок же убития глобальных объектов не оговорен стандартом:
и что умрет раньше - объект a или cout - никто не гарантирует. если программа, откомпиленная твоим конкретнымм компилятором, вывела строку
то это лишь говорит о том, что твой компилер расставил приоритеты именно в таком порядке. и это не значит, что другой компилятор поступит так же. поэтому я бы на это особо не расчитывал. прошу поправить меня, если я чего напутал или понял неправильно. Это сообщение отредактировал(а) blackofe - 10.1.2006, 21:28 |
||||
|
|||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |