1. 程式人生 > >C++在堆上建立物件還是在棧上建立物件

C++在堆上建立物件還是在棧上建立物件

對於程式碼:
Object obj;
obj是在棧上分配的嘛?
其實,這個語句的含義是,使物件obj具有“自動儲存的性質”,意思就是這個物件的儲存位置取決於其宣告所在的上下文。
如果這個語句出現在函式內部,那麼它就在棧上建立物件。
如果這個語句不是在函式內部,而是作為一個類的成員變數,則取決於這個類的物件是如何分配的。

class Class
{
    Object obj;
};

Class *pClass = new Class;

指標pClass所指向的物件在堆上分配空間。因為Object obj;語句的含義是“自動儲存”,所以,pClass->obj也是在堆上建立的。

Object *pObj;
pObj = new Object;

Object *pObj;代表,指標pObj是自動儲存的,僅此而已,沒有任何其它含義。而下面一行語句則指出,這個指標所指向的物件是在堆上面分配的。

至此,我們解釋了函式內部的變數和成員變數。還有兩類變數:全域性變數和static變數。它們即不在堆上建立,也不在棧上建立。它們有自己的記憶體空間,是除堆和棧以外的資料區。也就是說,當Object obj即不在函式內部,又不是類的成員變數時,這個物件會在全域性資料段建立,同理適用於static變數。對於指標Object *pObj;,如果這個語句出現在函式內部或類的成員變數,正如我們前面所說的,這個指標是自動儲存的。但是,如果這個語句是在類的外部,它就是在全域性資料段建立的。雖然它指向的物件可能在堆上建立,也可能在棧上建立。

**堆和棧的區別在於兩點:
1.生命週期
2.效能**
第一點才是我們需要著重考慮的。由於棧的特性,如果你需要一個具有比其所在的上下文更長的生命週期的變數,只能在堆上建立它。所以,我們的推薦是:只要能在棧上建立物件,就在棧上建立;否則的話,如果你不得不需要更長的生命週期,只能選擇堆上建立。這是由於在棧上的物件不需要我們手動管理記憶體。有經驗的開發人員都會對記憶體管理感到頭疼,我們就是要避免這種情況的發生。總的來說,我們更多推薦選擇在棧上建立物件。

但是,有些情況,即便你在棧上建立了物件,它還是會佔用堆的空間。考慮如下程式碼:

void func
{
    std::vector v
; }

物件v是在棧上建立的。但是,STL 的vector類其實是在堆上面儲存資料的(這點可以檢視原始碼)。因此,只有物件v本身是在棧上的,它所管理的資料(這些資料大多數時候都會遠大於其本身的大小)還是儲存在堆上。