讓“動態建立”、“靜態建立”、“動態記憶體分配”、“動態聯編”真相大白

來源:互聯網
上載者:User

前天發表的《MFC六大關鍵技術之剖析(三)》後,就遇到不少朋友的提問。而這些問題都讓我很驚訝——不知問的是什嗎?後來我算是明白了,因為有一個朋友問:“為了動態建立對象,要幹那麼多的事情嗎?究竟怎樣才算動態建立對象?”

我知道了他還沒有弄懂在MFC中動態建立的含義。在MFC的動態建立,比我們平時用new動態分配記憶體有著更深一層的意義。MFC的動態建立是在程式運行之後,在程式並未預測到將會獲得什麼樣的類名,比如程式開啟一個檔案,或接受一個來自鍵盤的字串,MFC程式能跟據你的輸入,產生一個對象。能夠完成這一功能的關鍵因素是CRuntimeClass鏈表。有了這個鏈表,我們就可以對程式說:“幫我‘生產’一個XXX。”程式預先並不知道XXX是個什麼樣的對象。它會回答:“我得在我的CRuntimeClass筆記本裡尋找一下,好,找到了,是這樣的東西,可以根據CRuntimeClass寫的要求生產了。”

關於動態建立的問題,你在我的MFC六大關鍵技術之剖析(四)——永久儲存,會有徹頭徹尾的理解。但我現在更關心的是另外一個問題。

剛才的問題讓我陷入深深的回憶中,彷彿又回到了好幾年以前。那時捧著一本C++程式,那個時候什麼也不懂,竟然在“動態”與“靜態”之間徘徊。每本書都很“清楚”地說:“編譯連結之前的記憶體配置就是靜態,程運行之後的分配就是動態!”

不說,我還有點明白,說了我更加不懂。因為我們只知道編譯連結是語言的翻譯過程,把原始碼轉換成電腦懂得的機器指令罷了。無論選擇任何的編譯器,最終目的只是更有效地產生一個可執行檔。既然是一個檔案,程式還沒有啟動並執行時候,它是以.EXE的副檔名儲存在磁碟中。

如果把編譯連結和運行間斷開來,程式在還沒有載入啟動並執行時候,它只是一個檔案,關記憶體什麼事?這還不算,絕大多數(幾乎我看到的都是)書本上在講多態性的時候,還講到一種“運行時綁定”,它的意思就是“在這些重載的函數中,可一系列虛函數中,編譯時間還不確定調用哪個函數,運行時就知道了!”

“屁話!通通都是屁話!”在我編程多年以後,才發覺書上寫得特錯大錯。試想一想,編譯器都不能確定將會調用那個函數,那麼程式運行之後又如何確定(當然,那些根據判斷和傳回值調等用的函數另當別論)。系統能確定嗎,系統是一個冰冷的機器,加上一個來料加工,甚至更多是被我們程式去操縱的作業系統,它如何能知道你自己寫程式直到編譯時間自己都弄不清楚的東西?其實在函數重載或虛函數當中,編譯器早就用按規則改名,或建立虛函數表,清清楚楚地確定將要調用的函數。

靜態與動態分配其實是一件很簡單的事情。

我們在載入程式的時候,系統要把我們的程式碼載入記憶體。

在程式真正運行之前,程式要為我們的一系列函數或對象分配空間和初始化,如全域對象或靜態變數,分配在靜態儲存地區內。在程式運行期間,那一Block Storage區跟程式本身聯絡在一起,我們不能刪除它。如我們定義了一個全域變數int x=100;我們不能試圖通過delete x;語句來釋放它。那一Block Storage地區從程式的生與死早已由程式“冥冥註定”,不待我們的代碼去判決。

局部對象也一樣,它的生命週期是從左大括弧開始,到右大括弧結束。期間在棧上被建立,出了棧就結束,它的生命也由程式本身決定。

動態記憶體分配就不同了,它在堆上分配,堆是一塊很大的記憶體。在上面分配記憶體就象軍閥割據一樣,一個軍閥的地界,可能馬上會被改寫。

我們可以從從左大括弧開始分配,但出了右大括弧並不代表那塊程式“死亡”——釋放。    當然,我們也可以隨時一句“delete 軍閥1”讓它即時變成可用記憶體。

動態記憶體分配在某些書上說成是用了new或者在堆分配的記憶體,甚至究其特點:分配的對象是沒有名字的,如:int *pi=new int;(注意,pi是指標名字,不要與它所指向的對象相混,先分配一個沒有名字的整形變數,再把變數地填給pi)。

但我覺得,之所以說成動態記憶體分配,是因為在堆分配記憶體非常靈活。就象一個動態數組,它可以在程式運行時增大、縮小、誕生、死亡,而這一切都在我們的程式語句之中去控制。

剛學c++時候,總覺得動態分配記憶體是一件很光榮的事。總認為動態就是自動的意思。後來才知道,對於記憶體配置,靜態才是自動的——自動分配與回收。

而動態分配,總是手動的,你要在最後手動回收記憶體。

動態分配會影響程式的執行效率,就象幹一件事情,需要某個“對象”的時候,才下命令去拿來,總不如靜態分配,所有“對象”都備在身邊,唾手可得。

 

 

我從來沒有回頭看過《MFC六大關鍵技術之剖析(三)》,因為我在寫《一》的時候就不能確定會不會往下寫。我覺得寫出來的東西好象沒有什麼朋友想看,一般是跟幾個帖罷了。我很想跟朋友們講:瞭解六大關鍵技術對學MFC的朋友來說走的是一個捷徑,要不,MFC編程對你來說永遠是個惡夢。但我知道這是個人的看法,可能真有朋友就在那兒添加控制項,添加訊息映射而寫出一個大好程式也是說不定的事情。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.