全局對象何時析構

 
我用下面的程序簡單測試了一下全局對象,它在main函數執行前被構造,但什麼時候析構呢?
#include   <iostream>
#include   <string>              
using   namespace   std;

class   Student
  {public:
      Student(int   n,string   nam,char   s)
        {num=n;
          name=nam;  
          sex=s;
          cout < < "Constructor   called. " < <num < <endl;
        }
      ~Student()
      {cout < < "Destructor   called. " < <num < <endl;}
     
    private:
        int   num;
        string   name;  
        char   sex;
};


Student   stud1(10010, "Wang_li ", 'f ');

int   main()
{
      Student   stud2(10011, "Zhang_fun ", 'm ');
      return   0;
}

運行結果:
Constructor   called.10010
Constructor   called.10011
Donstructor   called.10011

結果中沒有顯示出全局對象的析構信息,我跟蹤調試時也沒有查到,請問各位全局對象什麼時候被析構


20  修改 刪除 舉報 引用 回覆
id="Topic_Zone" marginwidth="0" marginheight="0" frameborder="0" width="100%" scrolling="no" height="0">
進入用戶個人空間
加爲好友
發送私信
在線聊天
  • xugang_2001
  • 等級:
  • 可用分等級:
  • 總技術分:
  • 總技術分排名:
發表於:2007-09-20 15:25:391樓 得分:1
全局對象可以理解爲在編譯階段就已經構造好了,所以會在mian之前就已經構造,至於析夠,肯定也是在main結束以後纔會發生,所以我們無法跟蹤,但是可想而知了。
修改 刪除 舉報 引用 回覆
進入用戶個人空間
加爲好友
發送私信
在線聊天
  • nkgd
  • 等級:
  • 可用分等級:
  • 總技術分:
  • 總技術分排名:
發表於:2007-09-20 15:26:412樓 得分:1
怎麼會沒有析構,運行輸出如下:
Constructor   called.10010
Constructor   called.10011
Destructor   called.10011
Destructor   called.10010
修改 刪除 舉報 引用 回覆
進入用戶個人空間
加爲好友
發送私信
在線聊天
  • ckt1120
  • 等級:
  • 可用分等級:
  • 總技術分:
  • 總技術分排名:
發表於:2007-09-20 15:35:113樓 得分:1
在main()函數退出時,或者exit()被調用時  
全局對象的析構被調用


你可以使用在析構中使用語句   OutputDebugString( "Destructor   called. ");  
//要include   Windows.h
用debugview查看
修改 刪除 舉報 引用 回覆
進入用戶個人空間
加爲好友
發送私信
在線聊天
  • wyylbl
  • 等級:
  • 可用分等級:
  • 總技術分:
  • 總技術分排名:
發表於:2007-09-20 15:54:564樓 得分:0
to   nkgd(長歌天下)  
我運行的結果只有
Constructor   called.10010
Constructor   called.10011
Donstructor   called.10011
沒有   Destructor   called.10010     這條語句啊!

修改 刪除 舉報 引用 回覆
進入用戶個人空間
加爲好友
發送私信
在線聊天
  • nkgd
  • 等級:
  • 可用分等級:
  • 總技術分:
  • 總技術分排名:
發表於:2007-09-20 15:57:245樓 得分:0
你什麼編譯器,什麼運行環境?
修改 刪除 舉報 引用 回覆
進入用戶個人空間
加爲好友
發送私信
在線聊天
  • fish6344
  • 等級:
  • 可用分等級:
  • 總技術分:
  • 總技術分排名:
發表於:2007-09-20 16:54:176樓 得分:5
首先,引用stanley   B.LLppman博士的一句話:

"C++保證,一定會在main()函數中第一次使用全局對象之前,把它構造出來,而在main()函數結束之前,把它摧毀掉! "

所以,全局對象的建構與析構是語言對我們的莊嚴承諾。

你的上述程序在VC、BC及Gcc是有不同的屏幕打印輸出,其中在我的一個非商業化Gcc編譯器上纔有一如我們預期的輸出:

Constructor   called.10010
Constructor   called.10011
Destructor   called.10011
Destructor   called.10010

現代C++編譯器(主要是指特定平臺的),通過擴充鏈接器和目標文件格式,完成全局對象的建構初始化和析構,(VC的鏈接器不是就把winmain()函數幫我們加入到.exe中,弄得許多學MFC的人看不到程序的主體而疑惑!),所以上述不同的編譯器對該程序有不同的表現,是因爲它們的鏈接器及目標文件格式,進一步說是對全局對象的靜態初始化與析構實現稍有不同的原故!但它們都一定實現了關於全局對象的建構與析構的語言特性。
修改 刪除 舉報 引用 回覆
進入用戶個人空間
加爲好友
發送私信
在線聊天
  • wwqna
  • 等級:
  • 可用分等級:
  • 總技術分:
  • 總技術分排名:
發表於:2007-09-20 17:16:457樓 得分:1
GCC可以輸出
修改 刪除 舉報 引用 回覆
進入用戶個人空間
加爲好友
發送私信
在線聊天
  • ivy1023
  • 等級:
  • 可用分等級:
  • 總技術分:
  • 總技術分排名:
發表於:2007-09-20 17:23:168樓 得分:2
實際在main()執行前,有段startup是要執行的,包括寄存器的初始化,全局變量的定義等等.
在main執行完後,也有段代碼要執行,而這段代碼就用來destruct全局對象.

可以只樣試,看程序是怎麼運行的;

在自己寫的某個類的構造函數中打一個斷點,析構函數中也打一個斷點,這樣就可以跟蹤其執行過程.
修改 刪除 舉報 引用 回覆
進入用戶個人空間
加爲好友
發送私信
在線聊天
  • fetag
  • 等級:
  • 可用分等級:
  • 總技術分:
  • 總技術分排名:
發表於:2007-09-20 19:35:579樓 得分:2
全局對象在main()之前被構造,在main()結束之後被析構。

但我只是說全局對象哦,不包括一些局部對象。例如下面的程序,全局對象沒有問題,局部對象

的析構函數則不會被調用,就是因爲“霸道”的exit()函數,看下面的代碼:

#include   <iostream>
#include   <cstdlib>
#include   <string>
using   namespace   std;

class   tmp{
public:
tmp(   string   s   )
{
cout < < "Constructor! " < <s < <endl;
str   =   s;
}
~tmp()
{
cout < < "Destructor! " < <str < <endl;
}
private:
string   str;
};

tmp   t1(   "t1 "   );

int   main()
{
tmp   t2(   "s2 "   );
//exit(   1   );

return   0;
}
運行結果如下:
Constructor!t1
Constructor!s2
Destructor!s2
Destructor!t1


Terminated   with   return   code   0
Press   any   key   to   continue   ...

如果把exit(1)的註釋去掉,結果是這樣的:
Constructor!t1
Constructor!s2
Destructor!t1


Terminated   with   return   code   1
Press   any   key   to   continue   ...

修改 刪除 舉報 引用 回覆
進入用戶個人空間
加爲好友
發送私信
在線聊天
  • nulldotnet
  • 等級:
  • 可用分等級:
  • 總技術分:
  • 總技術分排名:
發表於:2007-09-20 20:47:0610樓 得分:2
如果是vs   編譯器,   lz   可以去window   核心編程   -   進程章,   全局對象在mainz之前構造,   在main退出之後銷燬(前提是main   正常退出)。   如果某個線程   調用了   ::ExitProcess()   結束進程,   那麼全局對象不能夠被析夠,   但是進程結束後系統資源都會被回收。
修改 刪除 舉報 引用 回覆
進入用戶個人空間
加爲好友
發送私信
在線聊天
  • Chiyer
  • 等級:
  • 可用分等級:
  • 總技術分:
  • 總技術分排名:
  • 4

    4

    3

發表於:2007-09-20 21:03:0811樓 得分:1
alt   +   f5   運行

結果

Constructor   called.10010
Constructor   called.10011
Destructor   called.10011
Destructor   called.10010
請按任意鍵繼續.   .   .


修改 刪除 舉報 引用 回覆
進入用戶個人空間
加爲好友
發送私信
在線聊天
  • deng2000
  • 等級:
  • 可用分等級:
  • 總技術分:
  • 總技術分排名:
發表於:2007-09-20 21:48:1112樓 得分:2
樓主所遇到現象應該是全局變量析夠順序造成的.

注意cout本身也是一個全局變量.C++標準沒有規定全局變量的析夠順序(換句話說,順序依賴於編譯器).因此,在main()返回後,如果cout先被析夠,雖然stud1隨後也析構了,但其析構函數中cout < < "Destructor   called. "...一句會有問題,因爲cout已被銷燬了,可能什麼也不顯示(有可能更糟的結果是出異常,這依賴於cout的具體實現.一句話,結果不可預料).

如果用printf()而不是cout來顯示析構信息就不會有問題了.

這個小問題給我們一個提示:   不要在全局變量的析構函數中訪問另一個全局變量.你沒法知道它還在不在.
修改 刪除 舉報 引用 回覆
進入用戶個人空間
加爲好友
發送私信
在線聊天
  • fish6344
  • 等級:
  • 可用分等級:
  • 總技術分:
  • 總技術分排名:
發表於:2007-09-20 23:27:1613樓 得分:1
deng2000()   (   )   信譽:100   )說的也是問題的解的一部份,這也是我想補充我,呵,英雄所見略同!
修改 刪除 舉報 引用 回覆
進入用戶個人空間
加爲好友
發送私信
在線聊天
  • cmoring
  • 等級:
  • 可用分等級:
  • 總技術分:
  • 總技術分排名:
發表於:2007-09-21 13:59:4014樓 得分:1
在main退出後析構!
在windows的,exit/ExitProcess是無法析構全局對象的。
修改 刪除 舉報 引用 回覆
進入用戶個人空間
加爲好友
發送私信
在線聊天
  • wyylbl
  • 等級:
  • 可用分等級:
  • 總技術分:
  • 總技術分排名:
發表於:2007-09-21 14:19:3615樓 得分:0
謝謝大家!
我的編譯環境是VC6.0
修改 刪除 舉報 引用 回覆
進入用戶個人空間
加爲好友
發送私信
在線聊天
  • skyell
  • 等級:
  • 可用分等級:
  • 總技術分:
  • 總技術分排名:
發表於:2007-09-21 17:35:5816樓 得分:0
高深,深入學習
發佈了23 篇原創文章 · 獲贊 4 · 訪問量 28萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章