#c
#c
Вопрос:
Я начинающий программист, работающий над некоторым кодом для школы. При выполнении следующего кода выводится слово BAD. Я не понимаю, почему буква C в деструкторе не выводится при завершении объекта WriteLettersObj.
// Lab 1
//
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
class WriteLetters {
public:
WriteLetters();
void writeOneLetter();
~WriteLetters();
} WriteLettersObj;
WriteLetters::WriteLetters() {
cout << "B";
}
void WriteLetters::writeOneLetter() {
cout << "A";
}
WriteLetters::~WriteLetters() {
cout << "C" << endl;
}
int main() {
WriteLettersObj.writeOneLetter();
cout << "D";
getch();
return 0;
}
Комментарии:
1. Если удалить getch(), выводит ли он BADC? Я запускал в Unix через g , удалил getch () и stdafx / conio. h заголовки, и он выводит BADC.
2. Я попробовал это без getch (), это делает
3. Даже с
getch()
также это работает, единственное, что его экран исчезает, прежде чем он сможет увидеть результат. Посмотрите на мой ответ ниже.4. Вы уверены в результате?
std::cout
не уничтожается, поэтомуC
обязательно должно быть напечатано. (Зачем вы вообще вызываетеgetch()
? Кажется, это не имеет смысла.)5. @Джеймс Макнеллис — В Visual C 2010 окно вывода закрывается, и мы должны фактически установить точку останова в заключительном
return
операторе. Как только мы продолжим после этой точки останова, окно вывода get закрывается, и оператор вызова деструктораcout
не отображается. Я хочу сказать, что окно вывода немедленно закрывается, хотя деструктор фактически вызван. Таким образом, OP может на самом деле думать, что деструктор вообще не вызывается. Имея это в виду, я процитировал свой ответ. Дайте мне знать, если я ошибаюсь. @AI T — ideone.com/KEbu3
Ответ №1:
Вы смешиваете iostream с файлом conio.h, отличным от ANSI.
Внесите это изменение:
// getch();
cin.get();
Эй, вуаля, появляется C. По крайней мере, в OS X это происходит. И Ubuntu.
Комментарии:
1. ДА. Кажется, это имеет смысл.
2. Есть способы заставить C и C I / O хорошо взаимодействовать друг с другом, но в целом, не беспокойтесь и просто используйте исключительно один или другой.
3. @Mike DeSimone, как std::ios_base::sync_with_stdio? Будет ли это затронуто в наиболее вероятных реализациях conio?
4. Я не пробовал это, я только что увидел это. Хорошо ли это работает? Я полагаю, что при его частом использовании ввод-вывод больше похож на небуферизованный.
Ответ №2:
Ваша программа работает до тех пор, пока вы не завершите выполнение инструкции main()
with return 0
. Поскольку WriteLettersObj
это глобальная переменная, она будет создана перед main()
запуском и уничтожена после main()
завершения, а не после getch()
.
Чтобы увидеть, как печатаются ваши выходные данные, поместите getch()
в конец destructor .
Комментарии:
1. Спасибо, думаю, теперь я понял. Если бы объект был создан в main, вы бы его увидели. Поскольку его экземпляр создается перед main, он уничтожается после возврата 0.
2. Еще одна причина, по которой вы услышите, как люди говорят, что глобальных файлов следует избегать.
3. Объект iostream std::cout также создается перед main. Среда выполнения C создает std::cout как часть инициализации, которая происходит перед main , и уничтожает ее после main . Если вы не забыли включить функцию flush(), вы должны ожидать увидеть свой результат. Проблема в том, что вы записываете в объект std:: cout, но затем активируете подключение конкурирующей библиотеки к STDOUT с помощью conio::getch(), и это все портит. conio, вероятно, не знает об iostream; я предполагаю, что conio закрывает стандартный вывод, потому что думает, что он принадлежит ему, поэтому, когда iostream пытается выполнить окончательную запись и сброс, стандартный вывод пропадает.
Ответ №3:
Я попытался запустить ваш код без getch в Linux и Mac, и он работает просто отлично. @iammilind прав, что вам следует переместить getch в деструктор.
Комментарии:
1. Я использовал getch () как способ приостановить вывод, чтобы я мог увидеть, что там было до закрытия окна. Интересно, что если я помещу getch() в деструктор, вы увидите, что выводится C. Итак, вы правы, оно действительно есть, но время закрытия окна не позволяет вам его увидеть.
2. Лучшая идея оставить окно открытым — запустить программу в окне ‘cmd’ (при условии, что вы используете Windows)