C++棧對象,堆對象,靜態對象的理解

棧對象

的優勢是在適當的時候自動生成,又在適當的時候自動銷燬,不需要程序員操心;而且棧對象的創建速度一般較堆對象快,因爲分配堆對象時,會調用operator new操作,operator new會採用某種內存空間搜索算法,而該搜索過程可能是很費時間的,產生棧對象則沒有這麼麻煩,它僅僅需要移動棧頂指針就可以了。但是要注意的是,通常棧空間容量比較小,一般是1MB~2MB,所以體積比較大的對象不適合在棧中分配。特別要注意遞歸函數中最好不要使用棧對象,因爲隨着遞歸調用深度的增加,所需的棧空間也會線性增加,當所需棧空間不夠時,便會導致棧溢出,這樣就會產生運行時錯誤。

堆對象

其產生時刻和銷燬時刻都要程序員精確定義,也就是說,程序員對堆對象的生命具有完全的控制權。我們常常需要這樣的對象,比如,我們需要創建一個對象,能夠被多個函數所訪問,但是又不想使其成爲全局的,那麼這個時候創建一個堆對象無疑是良好的選擇,然後在各個函數之間傳遞這個堆對象的指針,便可以實現對該對象的共享。另外,相比於棧空間,堆的容量要大得多。實際上,當物理內存不夠時,如果這時還需要生成新的堆對象,通常不會產生運行時錯誤,而是系統會使用虛擬內存來擴展實際的物理內存。

static對象

首先是全局對象。全局對象爲類間通信和函數間通信提供了一種最簡單的方式,雖然這種方式並不優雅。一般而言,在完全的面嚮對象語言中,是不存在全局對象的,比如C#,因爲全局對象意味着不安全和高耦合,在程序中過多地使用全局對象將大大降低程序的健壯性、穩定性、可維護性和可複用性。C++也完全可以剔除全局對象,但是最終沒有,我想原因之一是爲了兼容C。

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

接着是靜態局部對象,主要可用於保存該對象所在函數被屢次調用期間的中間狀態,其中一個最顯著的例子就是遞歸函數,我們都知道遞歸函數是自己調用自己的函數,如果在遞歸函數中定義一個nonstatic局部對象,那麼當遞歸次數相當大時,所產生的開銷也是巨大的。這是因爲nonstatic局部對象是棧對象,每遞歸調用一次,就會產生一個這樣的對象,每返回一次,就會釋放這個對象,而且,這樣的對象只侷限於當前調用層,對於更深入的嵌套層和更淺露的外層,都是不可見的。每個層都有自己的局部對象和參數。

在遞歸函數設計中,可以使用static對象替代nonstatic局部對象(即棧對象),這不僅可以減少每次遞歸調用和返回時產生和釋放nonstatic對象的開銷,而且static對象還可以保存遞歸調用的中間狀態,並且可爲各個調用層所訪問。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章