2011-05-11 71 views
1

我是一个为学校编写代码的新手程序员。当执行下面的代码时,会输出BAD字。我不明白为什么在WriteLettersObj对象终止时不会输出析构函数中的字母C.C++析构函数异常

// 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; 
} 
+0

如果删除getch()是否打印出BADC?我通过g ++在Unix上运行,删除了getch()和stdafx/conio.h头文件,并打印出BADC。 – Suroot 2011-05-11 03:16:48

+0

我试过它没有getch(),它确实 – 2011-05-11 03:18:19

+0

即使'getch()'也行,唯一的事情是他的屏幕在他看到输出之前就消失了。请看下面的答案。 – iammilind 2011-05-11 03:19:21

回答

2

您正在将iostream与非ANSI conio.h混合使用。

使这一变化:

// getch(); 
cin.get(); 

变戏法似的,在C出现。至少在OS X上它有。和Ubuntu。

+0

是的。这似乎是有道理的。 – 2011-05-11 03:22:07

+0

有许多方法可以使C++和C I/O相互之间更好地发挥作用,但总的来说,不要打扰并只使用其中一种。 – 2011-05-11 03:31:24

+0

@Mike DeSimone,像std :: ios_base :: sync_with_stdio?这会达到conio的最合理的实现吗? – 2011-05-11 03:45:22

1

直到您退出main()return 0指令为止,您的程序一直保持活动状态。由于WriteLettersObj是一个全局变量,因此将在main()开始之前构建,并在main()完成之后破坏,而不是在getch()之后构建。

要查看输出得到打印,请将getch()置于析构函数的末尾。

+0

谢谢,我想我现在明白了。如果对象在main中被实例化,你会看到它。由于它在main之前被实例化,它在返回0后被破坏。 – 2011-05-11 03:21:21

+0

另一个你会听到人们说应该避免全局变量的原因。 – 2011-05-11 03:30:18

+1

iostream对象std :: cout也在main之前实例化。 C++运行时创建std :: cout作为main之前发生的初始化的一部分,并在main之后将其销毁。如果你记得flush(),你应该期望看到你的输出。问题在于你正在写入std :: cout对象,但是随后使用conio :: getch()激活竞争库的钩子到STDOUT,并且这会混淆。 conio可能不知道iostream;我的猜测是Conio正在关闭STDOUT,因为它认为它拥有它,所以当iostream尝试执行最后的写入和刷新时,STDOUT消失了。 – 2011-05-11 03:36:53

0

我试着运行你的代码没有 getch在Linux和Mac上,它运行得很好。 @iammilind是正确的,你应该将getch移动到析构函数中。

+0

我使用getch()作为暂停输出的方式,以便在窗口关闭之前可以看到有什么。有趣的是,如果我在析构函数中放置getch(),则会看到C正在输出。所以你是对的,它实际上在那里,但窗户关闭的时间不允许你看到它。 – 2011-05-11 03:43:06

+0

保持窗口打开的更好的方法是在'cmd'窗口中运行程序(假设你在Windows上) – 2011-05-11 03:45:03