Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Деструктор не изменяет состояние потока, В чем дело? 
:(
    Опции темы
Nitro89
Дата 8.1.2006, 19:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 18.3.2005

Репутация: нет
Всего: нет



Вообщем, пытаясь выполнить упражнение Бьерна Страуструпа, я написал такой код.
Код

class A
{
public:
A() { std::cout<<"Initialization.\n"; }
~A() { std::cout<<"Destroing.\n"; }
};
A a;
int main()
{
std::cout<<"Work.";
return 0;
}

И почему в результате выполнения программы, я увидел только две строчки, а не три, т.е. я увидел только "Initialization." и "Work.". Куда третья делась, ведь деструктор класса A полюбому вызывается. Может, std::cout уничтожается до того, как уничтожится a?
Объясните пожалуйста.
PM MAIL ICQ   Вверх
TIGERоX
Дата 8.1.2006, 20:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


начинающий...
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 7.9.2005

Репутация: нет
Всего: 1



пройдитесь дебугером все нормально деструктор вызывается при выходе объекта за предел видимости если вы поставил например getch перед return ток конечно в консоли ничего не увидите потомучто она уже спрячется перед тем как вызывется деструктор smile

Это сообщение отредактировал(а) TIGERоX - 8.1.2006, 20:08
PM MAIL   Вверх
chipset
Дата 8.1.2006, 21:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4071
Регистрация: 11.1.2003
Где: Seattle, US

Репутация: 27
Всего: 164



Компилятор?


--------------------
Цитата(Jimi Hendrix)
Well, I stand up next to a mountain
And I chop it down with the edge of my hand
PM MAIL WWW   Вверх
Mephistopheles
Дата 9.1.2006, 10:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегущий от света
*


Профиль
Группа: Участник
Сообщений: 146
Регистрация: 15.11.2005
Где: Где нет света

Репутация: нет
Всего: 6



По-моему переменную типа A надо объявить в функции main.
--------------------
Ангелы и бесы кружат надо мной.Ангел или бес - делай выбор свой.Вспыхнуть огнём; вознестись до небесДелай выбор свой: ангел или бес?© Mephistopheles, бегущий от света.
PM MAIL WWW ICQ   Вверх
chipset
Дата 9.1.2006, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4071
Регистрация: 11.1.2003
Где: Seattle, US

Репутация: 27
Всего: 164



Это глобальная переменная а вот кажеться компилятор я узнаю -- BCB smile Он любит такое учудить, интересно с какого перепоя его писали...


--------------------
Цитата(Jimi Hendrix)
Well, I stand up next to a mountain
And I chop it down with the edge of my hand
PM MAIL WWW   Вверх
Nitro89
Дата 9.1.2006, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 18.3.2005

Репутация: нет
Всего: нет



Цитата(chipset @ 9.1.2006, 11:00 Найти цитируемый пост)

Это глобальная переменная а вот кажеться компилятор я узнаю -- BCB  Он любит такое учудить, интересно с какого перепоя его писали...

Э нее браток, обознался. MS Visual C++ 6.0....
PM MAIL ICQ   Вверх
threef
Дата 9.1.2006, 21:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 27.10.2005
Где: Запорожье

Репутация: 9
Всего: 10



Цитата

Код

~A() { std::cout<<"Destroing.\n";

     

добавь

std::cout.flush();

Ну уж очень навороченный cout. Он такой оптимизированный !
Лучше бы setlocale к нему прикрутили smile

Это сообщение отредактировал(а) threef - 9.1.2006, 21:36
PM MAIL   Вверх
Hearse
Дата 9.1.2006, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 13.1.2004

Репутация: нет
Всего: нет



Прикол в том, что код инициализации/завершения вызывает CRT, посему вызов деструктора A происходит после того, как функция main вернет управление.
Код

class A
{
public:
A() { std::cout<<"Initialization.\n"; }
~A() { std::cout<<"Destroing.\n"; }
};

int main()
{
    {
         A a;
         
         std::cout<<"Work." ; 
    }

     return 0;
}

Вот такой код покажет все как ты хотел увидеть.

Это сообщение отредактировал(а) Hearse - 9.1.2006, 23:30
PM MAIL   Вверх
blackofe
Дата 9.1.2006, 22:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 173
Регистрация: 29.11.2005

Репутация: 4
Всего: 4



Hearse

в main() можно и без дополнительных скобок обойтись. вот так тоже будет работать:

Код

int main()
{
    A a;

    std::cout << "Work." << endl; 

    return 0;
}


а вот с изначальным кодом вопрос интересный. у меня (vc++ 7.1.3088) такой код

Код

#include <iostream>

class A {
public:
    A()            {    std::cout << "Initialization." << endl; }
    ~A()        {    std::cout << "Destroing." << endl; }
};

A a;

int main()
{
    std::cout << "Work." << endl; 

    return 0;
}


выдал

Код

Initialization.
Work.
Destroing.
Press any key to continue


так что, мне кажется, что в подобном случае порядок уничтожения глобальных объектов неопределен. и разные компилеры это могут делать по-разному. а что в данном случает "глобальнее" - А или cout - я бы не взялся решить smile.
PM MAIL   Вверх
Void
Дата 9.1.2006, 23:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 40
Всего: 173



Цитата(threef @ 9.1.2006, 23:31 Найти цитируемый пост)
Лучше бы setlocale к нему прикрутили

Здрасьте. А imbue что такое?


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
Hearse
Дата 9.1.2006, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 13.1.2004

Репутация: нет
Всего: нет



blackofe Момент вызова завершающего кода CRT не определяется стандартом, например в Mingw/GCC 3.4.2 выводится только две строчки.
Об'являя же 'а' в блоке {} можно быть уверенным, что деструктор вызовется до завершения main().

Это сообщение отредактировал(а) Hearse - 9.1.2006, 23:24
PM MAIL   Вверх
blackofe
Дата 10.1.2006, 01:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 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;

так что, вполне в соответствии со стандартом вот такой код

Код
#include <iostream>

class A {
public:
    A()            {    std::cout << "Initialization." << endl; }
    ~A()        {    std::cout << "Destroing." << endl; }
};

int main()
{
    A a;

    std::cout << "Work." << endl; 

    return 0;
}


должен вывести

Код

Initialization.
Work.
Destroing.


а вот такой

Код
#include <iostream>

class A {
public:
    A()            {    std::cout << "Initialization." << endl; }
    ~A()        {    std::cout << "Destroing." << endl; }
};

int main()
{
    A a;

    std::cout << "Work." << endl; 

    exit(0);

    return 0;
}


должен вывести:

Код

Initialization.
Work.


и, кстати говоря, VC++ 7.1 именно так и работает. и нигде в стандарте не написано, что выход из функции main является implementation-defined.

ну, а Mingw/GCC 3.4.2 с его нестрогим следованием стандарту придется засунуть.. куда-нибудь.. ;)

можно сказать больше. вот такой код

Код
#include <iostream>

class A {
public:
    A()            {    std::cout << "Initialization." << endl; }
    ~A()        {    std::cout << "Destroing." << endl; }
};

int main()
{
    A a;

    std::cout << "Work." << endl; 
}


также выведет

Код

Initialization.
Work.
Destroing.


и опять таки в соответствии со стандартом (последнее предложение 3.6.1.5).

Это сообщение отредактировал(а) blackofe - 10.1.2006, 01:08
PM MAIL   Вверх
Hearse
Дата 10.1.2006, 01:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 13.1.2004

Репутация: нет
Всего: нет



blackofe Сорри, проглядел - GCC сразу закрывает консоль , просто мне думалось, что он разрушает консоль после return, и не дает вывести "Destroing"

такой код все прекрасно показывает
Код


#include <iostream>

#include <conio.h>

using namespace std;

class A {
public:
    A()            {    std::cout << "Initialization." << endl; }
    ~A()        {    std::cout << "Destroing." << endl; getch(); }
};

A a;

int main()
{
    std::cout << "Work." << endl; 
    return 0;
}

З.Ы. Про станарт и CRT я имел в виду что не определяется порядок разрушение консоли-разрушение об'ектов.

Это сообщение отредактировал(а) Hearse - 10.1.2006, 01:32
PM MAIL   Вверх
threef
Дата 10.1.2006, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 27.10.2005
Где: Запорожье

Репутация: 9
Всего: 10



blackofe
С твоими обьяснениями завершения функции main никак не вяжется простейший пример
Код

class A
{
public:
A() { printf("Initialization.\n");}
~A() {printf("Destroing\n");}
};
A a;
void main()
{
std::cout<<"work.";
}



Обьект 'a' преспокойненько разрушается, так что exit() тут ни при чем. И CRT нормально продолжает отрабатывать(stdout существует). Все дело в cout, если проверить, то его состояние
good() становится вовсе не good:

~A() {printf("Destroing %d\n",std::cout.good());}

голобальные обьекты создаются ДО main, разрушаются после,

и даже использование внутри main exit() не меняет ситуации

Код

class A
{
public:
A() { printf("Initialization.\n");}
~A() {printf("Destroing.\n");}
};
A a;
int main()
{
std::cout<<"work.\n";
exit(3);
return 0;
}



результат -
Код

Initializatiion.
work.
Destroying.



PM MAIL   Вверх
blackofe
Дата 10.1.2006, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 173
Регистрация: 29.11.2005

Репутация: 4
Всего: 4



threef
почему же не вяжется? мы с Hearse'ом обсуждали, нужны ли внутри функции main скобки, чтобы быть уверенным, что деструктор объекта, объявленного внутри функции main, нормально отработает по завершению работы. и мы узнали из стандарта, что все произойдет вполне миленько, если пользоваться return'ом, и нужно быть осторожным при использовании exit().

а у тебя объект a объявлен глобально. и убиваться он будет вместе с другими глобальными объектами. порядок же убития глобальных объектов не оговорен стандартом:

Код

3.6.1.1.
Note: in a freestanding environment, start-up and termination is implementation-defined;
startup contains the execution of constructors for objects of namespace scope with static
storage duration; termination contains the execution of destructors for objects with static
storage duration.


и что умрет раньше - объект a или cout - никто не гарантирует. если программа, откомпиленная твоим конкретнымм компилятором, вывела строку

Код
Destroying.


то это лишь говорит о том, что твой компилер расставил приоритеты именно в таком порядке. и это не значит, что другой компилятор поступит так же. поэтому я бы на это особо не расчитывал.

прошу поправить меня, если я чего напутал или понял неправильно.

Это сообщение отредактировал(а) blackofe - 10.1.2006, 21:28
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0917 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.