棧物件 堆物件 靜態物件的比較

2021-09-01 03:10:39 字數 2370 閱讀 4083

棧物件的優勢是在適當的時候自動生成,又在適當的時候自動銷毀,不需要程式設計師操心;

而且棧物件的建立速度一般較堆物件快,因為分配堆物件時,會呼叫operator new操作,operator new會採用某種記憶體空間搜尋演算法,而該搜尋過程可能是很費時間的,產生棧物件則沒有這麼麻煩,它僅僅需要移動棧頂指標就可以了。

但是要注意的是,通常棧空間容量比較小,一般是1mb~2mb,所以體積比較大的物件不適合在棧中分配。特別要注意遞迴函式中最好不要使用棧物件,因為隨著遞迴呼叫深度的增加,所需的棧空間也會線性增加,當所需棧空間不夠時,便會導致棧溢位,這樣就會產生執行時錯誤。   

堆物件,其產生時刻和銷毀時刻都要程式設計師精確定義,也就是說,程式設計師對堆物件的生命具有完全的控制權。我們常常需要這樣的物件,比如,我們需要建立乙個物件,能夠被多個函式所訪問,但是又不想使其成為全域性的,那麼這個時候建立乙個堆物件無疑是良好的選擇,然後在各個函式之間傳遞這個堆物件的指標,便可以實現對該物件的共享。

另外,相比於棧空間,堆的容量要大得多。實際上,當物理記憶體不夠時,如果這時還需要生成新的堆物件,通常不會產生執行時錯誤,而是系統會使用虛擬記憶體來擴充套件實際的物理記憶體。

接下來看看static物件。   

首先是全域性物件。全域性物件為類間通訊和函式間通訊提供了一種最簡單的方式,雖然這種方式並不優雅。一般而言,在完全的物件導向語言中,是不存在全域性物件的,比如c#,因為全域性物件意味著不安全和高耦合,在程式中過多地使用全域性物件將大大降低程式的健壯性、穩定性、可維護性和可復用性。c++也完全可以剔除全域性物件,但是最終沒有,我想原因之一是為了相容c。   

其次是類的靜態成員,上面已經提到,基類及其派生類的所有物件都共享這個靜態成員物件,所以當需要在這些class之間或這些class objects之間進行資料共享或通訊時,這樣的靜態成員無疑是很好的選擇。   

接著是靜態區域性物件,主要可用於儲存該物件所在函式被屢次呼叫期間的中間狀態,其中乙個最顯著的例子就是遞迴函式,我們都知道遞迴函式是自己呼叫自己的函式,如果在遞迴函式中定義乙個nonstatic區域性物件,那麼當遞迴次數相當大時,所產生的開銷也是巨大的。這是因為nonstatic區域性物件是棧物件,每遞迴呼叫一次,就會產生乙個這樣的物件,每返回一次,就會釋放這個物件,而且,這樣的物件只侷限於當前呼叫層,對於更深入的巢狀層和更淺露的外層,都是不可見的。每個層都有自己的區域性物件和引數。   

在遞迴函式設計中,可以使用static物件替代nonstatic區域性物件(即棧物件),這不僅可以減少每次遞迴呼叫和返回時產生和釋放nonstatic物件的開銷,而且static物件還可以儲存遞迴呼叫的中間狀態,並且可為各個呼叫層所訪問。

********************==

在gameres上看見乙個問題帖:

什麼時候該用 object object;

什麼時候該用 object *object;

object=new object();

感覺看起來沒什麼區別,其實不一樣:前乙個是棧物件,後乙個是堆物件。

引用一下別人對棧物件、堆物件的解釋:

棧物件的優勢是在適當的時候自動生成,又在適當的時候自動銷毀,不需要程式設計師操心;而且棧物件的建立速度一般較堆物件快,因為分配堆物件時,會呼叫 operator new操作,operator new會採用某種記憶體空間搜尋演算法,而該搜尋過程可能是很費時間的,產生棧物件則沒有這麼麻煩,它僅僅需要移動棧頂指標就可以了。但是要注意的是,通常棧空間容量比較小,一般是1mb~2mb,所以體積比較大的物件不適合在棧中分配。特別要注意遞迴函式中最好不要使用棧物件,因為隨著遞迴呼叫深度的增加,所需的棧空間也會線性增加,當所需棧空間不夠時,便會導致棧溢位,這樣就會產生執行時錯誤。

堆物件,其產生時刻和銷毀時刻都要程式設計師精確定義,也就是說,程式設計師對堆物件的生命具有完全的控制權。我們常常需要這樣的物件,比如,我們需要建立乙個物件,能夠被多個函式所訪問,但是又不想使其成為全域性的,那麼這個時候建立乙個堆物件無疑是良好的選擇,然後在各個函式之間傳遞這個堆物件的指標,便可以實現對該物件的共享。另外,相比於棧空間,堆的容量要大得多。實際上,當物理記憶體不夠時,如果這時還需要生成新的堆物件,通常不會產生執行時錯誤,而是系統會使用虛擬記憶體來擴充套件實際的物理記憶體。

所以當你知道你要使用的型別擁有準確數量時使用 object object;

當你不知道你要建立的型別有多少個時使用

object *object;

object=new object();

***************==

先說一下區域性物件的性質,在第一次執行到的時候初始化,而在最後的時候析構,也就是說如果它生成後,在程式的執行期,它都是有效的,存在於靜態儲存區,儘管它往往不是時時可見,但可以經由指標操作它,因為它一直都在。

使用區域性靜態物件的singleton就是這個原理,解決的主要問題是singleton的析構問題。本書中,對區域性靜態物件的處理還是很巧妙的。我寫的測試程式也證明了區域性靜態物件的性質,無論訪問物件定義多少次,始終只有一次物件構造和析構

C 棧物件,堆物件,靜態物件的理解

的優勢是在適當的時候自動生成,又在適當的時候自動銷毀,不需要程式設計師操心 而且棧物件的建立速度一般較堆物件快,因為分配堆物件時,會呼叫operator new操作,operator new會採用某種記憶體空間搜尋演算法,而該搜尋過程可能是很費時間的,產生棧物件則沒有這麼麻煩,它僅僅需要移動棧頂指標...

棧物件和堆物件

在gameres上看見乙個問題帖 什麼時候該用 object object 什麼時候該用 object object object new object 感覺看起來沒什麼區別,其實不一樣 前乙個是棧物件,後乙個是堆物件。引用一下別人對棧物件 堆物件的解釋 棧物件的優勢是在適當的時候自動生成,又在適當...

C 棧物件 堆物件 理解

在c 中,類的物件建立分為兩種,一種是靜態建立,如a a 另一種是動態建立,如a ptr new a 這兩種方式是有區別的。1 靜態建立類物件 是由編譯器為物件在棧空間中分配記憶體,是通過直接移動棧頂指標,挪出適當的空間,然後在這片記憶體空間上呼叫建構函式形成乙個棧物件。使用這種方法,直接呼叫類的建...