栈对象、堆对象、静态对象的比较
生活随笔
收集整理的這篇文章主要介紹了
栈对象、堆对象、静态对象的比较
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
棧對象的優(yōu)勢是在適當(dāng)?shù)臅r候自動生成,又在適當(dāng)?shù)臅r候自動銷毀,不需要程序員操心;而且棧對象的創(chuàng)建速度一般較堆對象快,因?yàn)榉峙涠褜ο髸r,會調(diào)用operator new操作,operator new會采用某種內(nèi)存空間搜索算法,而該搜索過程可能是很費(fèi)時間的,產(chǎn)生棧對象則沒有這么麻煩,它僅僅需要移動棧頂指針就可以了。但是要注意的是,通常棧空間容量比較小,一般是1MB~2MB,所以體積比較大的對象不適合在棧中分配。特別要注意遞歸函數(shù)中最好不要使用棧對象,因?yàn)殡S著遞歸調(diào)用深度的增加,所需的棧空間也會線性增加,當(dāng)所需棧空間不夠時,便會導(dǎo)致棧溢出,這樣就會產(chǎn)生運(yùn)行時錯誤。
堆對象,其產(chǎn)生時刻和銷毀時刻都要程序員精確定義,也就是說,程序員對堆對象的生命具有完全的控制權(quán)。我們常常需要這樣的對象,比如,我們需要創(chuàng)建一個對象,能夠被多個函數(shù)所訪問,但是又不想使其成為全局的,那么這個時候創(chuàng)建一個堆對象無疑是良好的選擇,然后在各個函數(shù)之間傳遞這個堆對象的指針,便可以實(shí)現(xiàn)對該對象的共享。另外,相比于棧空間,堆的容量要大得多。實(shí)際上,當(dāng)物理內(nèi)存不夠時,如果這時還需要生成新的堆對象,通常不會產(chǎn)生運(yùn)行時錯誤,而是系統(tǒng)會使用虛擬內(nèi)存來擴(kuò)展實(shí)際的物理內(nèi)存。
?
接下來看看static對象。
首先是全局對象。全局對象為類間通信和函數(shù)間通信提供了一種最簡單的方式,雖然這種方式并不優(yōu)雅。一般而言,在完全的面向?qū)ο笳Z言中,是不存在全局對象的,比如C#,因?yàn)槿謱ο笠馕吨话踩透唏詈?#xff0c;在程序中過多地使用全局對象將大大降低程序的健壯性、穩(wěn)定性、可維護(hù)性和可復(fù)用性。C++也完全可以剔除全局對象,但是最終沒有,我想原因之一是為了兼容C。
其次是類的靜態(tài)成員,上面已經(jīng)提到,基類及其派生類的所有對象都共享這個靜態(tài)成員對象,所以當(dāng)需要在這些class之間或這些class objects之間進(jìn)行數(shù)據(jù)共享或通信時,這樣的靜態(tài)成員無疑是很好的選擇。
接著是靜態(tài)局部對象,主要可用于保存該對象所在函數(shù)被屢次調(diào)用期間的中間狀態(tài),其中一個最顯著的例子就是遞歸函數(shù),我們都知道遞歸函數(shù)是自己調(diào)用自己的函數(shù),如果在遞歸函數(shù)中定義一個nonstatic局部對象,那么當(dāng)遞歸次數(shù)相當(dāng)大時,所產(chǎn)生的開銷也是巨大的。這是因?yàn)閚onstatic局部對象是棧對象,每遞歸調(diào)用一次,就會產(chǎn)生一個這樣的對象,每返回一次,就會釋放這個對象,而且,這樣的對象只局限于當(dāng)前調(diào)用層,對于更深入的嵌套層和更淺露的外層,都是不可見的。每個層都有自己的局部對象和參數(shù)。
在遞歸函數(shù)設(shè)計中,可以使用static對象替代nonstatic局部對象(即棧對象),這不僅可以減少每次遞歸調(diào)用和返回時產(chǎn)生和釋放nonstatic對象的開銷,而且static對象還可以保存遞歸調(diào)用的中間狀態(tài),并且可為各個調(diào)用層所訪問。
堆對象,其產(chǎn)生時刻和銷毀時刻都要程序員精確定義,也就是說,程序員對堆對象的生命具有完全的控制權(quán)。我們常常需要這樣的對象,比如,我們需要創(chuàng)建一個對象,能夠被多個函數(shù)所訪問,但是又不想使其成為全局的,那么這個時候創(chuàng)建一個堆對象無疑是良好的選擇,然后在各個函數(shù)之間傳遞這個堆對象的指針,便可以實(shí)現(xiàn)對該對象的共享。另外,相比于棧空間,堆的容量要大得多。實(shí)際上,當(dāng)物理內(nèi)存不夠時,如果這時還需要生成新的堆對象,通常不會產(chǎn)生運(yùn)行時錯誤,而是系統(tǒng)會使用虛擬內(nèi)存來擴(kuò)展實(shí)際的物理內(nèi)存。
?
接下來看看static對象。
首先是全局對象。全局對象為類間通信和函數(shù)間通信提供了一種最簡單的方式,雖然這種方式并不優(yōu)雅。一般而言,在完全的面向?qū)ο笳Z言中,是不存在全局對象的,比如C#,因?yàn)槿謱ο笠馕吨话踩透唏詈?#xff0c;在程序中過多地使用全局對象將大大降低程序的健壯性、穩(wěn)定性、可維護(hù)性和可復(fù)用性。C++也完全可以剔除全局對象,但是最終沒有,我想原因之一是為了兼容C。
其次是類的靜態(tài)成員,上面已經(jīng)提到,基類及其派生類的所有對象都共享這個靜態(tài)成員對象,所以當(dāng)需要在這些class之間或這些class objects之間進(jìn)行數(shù)據(jù)共享或通信時,這樣的靜態(tài)成員無疑是很好的選擇。
接著是靜態(tài)局部對象,主要可用于保存該對象所在函數(shù)被屢次調(diào)用期間的中間狀態(tài),其中一個最顯著的例子就是遞歸函數(shù),我們都知道遞歸函數(shù)是自己調(diào)用自己的函數(shù),如果在遞歸函數(shù)中定義一個nonstatic局部對象,那么當(dāng)遞歸次數(shù)相當(dāng)大時,所產(chǎn)生的開銷也是巨大的。這是因?yàn)閚onstatic局部對象是棧對象,每遞歸調(diào)用一次,就會產(chǎn)生一個這樣的對象,每返回一次,就會釋放這個對象,而且,這樣的對象只局限于當(dāng)前調(diào)用層,對于更深入的嵌套層和更淺露的外層,都是不可見的。每個層都有自己的局部對象和參數(shù)。
在遞歸函數(shù)設(shè)計中,可以使用static對象替代nonstatic局部對象(即棧對象),這不僅可以減少每次遞歸調(diào)用和返回時產(chǎn)生和釋放nonstatic對象的開銷,而且static對象還可以保存遞歸調(diào)用的中間狀態(tài),并且可為各個調(diào)用層所訪問。
轉(zhuǎn)載于:https://www.cnblogs.com/taoxu0903/archive/2007/10/08/917546.html
總結(jié)
以上是生活随笔為你收集整理的栈对象、堆对象、静态对象的比较的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 冯小刚导演系列公益短片之林心如版
- 下一篇: (原创)无废话C#设计模式之十一:Com