天天看點

探讨全局變量的析構順序

                                                                        朱金燦

前言:最近回答了網友一個問題,當然我不是C++高手,我僅是提出我的猜想和大家交流。

  經典的C++的教科書都這樣寫着:全局對象在調用 main之前初始化, 在退出main之後析構。但是大家請看下面這樣一個程式:

#include <cstdlib>

#include <iostream>

#include <conio.h>

class gb

{

public:

gb::gb()

{

std::cout<<"start"<<std::endl;

};

gb::~gb()

{

std::cout<<"end"<<std::endl;

getch();

};

};

gb a;

int main()

{

std::cout<<"This is in main"<<std::endl;

return 0;

}

    大家認為輸出是什麼呢?大家可能會說:這不是很簡單嗎?

Start

This is in main

End

     實際上事情并沒有這麼簡單。在dev-c++-4.9.9.2的工程上,輸出結果是順理成章的:

Start

This is in main

End

在VC6.0上建一個控制台工程,把代碼拷貝進去,發現運作結果卻是:

Start

This is in main

    當時很感疑惑,難道gb類對象a沒有執行析構函數?思考了一會,決定試驗一下。把代碼稍為修改一下,把cout全部換為C語言的printf()函數,如下:

#include <cstdlib>

#include <iostream>

#include <conio.h>

#include <stdio.h>

class gb

{

public:

gb::gb()

{

//std::cout<<"start"<<std::endl;

printf("start/n");

};

gb::~gb()

{

// std::cout<<"end"<<std::endl;

printf("end/n");

getch();

};

};

gb a;

int main()

{

std::cout<<"This is in main"<<std::endl;

return 0;

}

運作結果是:

Start

This is in main

End

這說明析構函數是有執行的。下面提出我的一個猜想:cout作為一個iostream類的對象,在退出main函數後比gb類對象a先執行析構函數,故無法輸出End。值得注意這種全局變量的析構順序是和編譯器相關的,在VC上是cout ——〉gb a,而在dev-c++-4.9.9.2是gb a——〉cout。實際上C++标準隻規定了同一個cpp檔案裡的全局變量的構造和析構順序,