2011-05-11 120 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