c 只在堆和只在棧上建立物件

2021-09-27 13:32:43 字數 1296 閱讀 7992

首先,分享一篇講解的很詳細的文章:

其次,說下這裡面涉及到的一些基礎知識:c++的記憶體分配,類的成員函式的訪問修飾符。

物件在記憶體中可以儲存在堆上也可以儲存在棧上。靜態建立的物件在棧上,好處是棧空間的申請效率高(編譯器有直接處理的指令),作業系統會幫助管理變數的記憶體,當超出作用域後會被直接析構掉,不用擔心記憶體洩漏的問題。但是棧空間比較小,一般在10m以內,這個值也可以手動調整,linux環境中`uname -s`可以檢視。

動態建立的物件在堆上。物件的記憶體資源由程式設計師控制,自己控制什麼時候去釋放。和上一種的區別是:變數的生命週期是可控的,不會因為作用域的原因而被釋放(如果忘記釋放就會出現記憶體洩漏的問題)。

當使用靜態建立物件的方法即`test test;`,編譯器會在棧空間上申請出test類的一塊空間,並且將類的析構函式註冊進來,當該物件退出作用域後,析構掉test物件的棧空間。當動態建立物件的時候`test* test = new test();`,new是乙個操作符號(和+-符號一樣),會先申請出來乙個空間,然後再呼叫class的建構函式進行構造。這個物件一直在記憶體上,直到有程式設計師呼叫了delete才會釋放調這個空間。可以發現,建立物件的時候都避不開建構函式和析構函式,所以可以採用設定建構函式和析構函式的訪問可見性來控制物件是生成在棧上還是堆上。

如果想讓物件只能在堆上,那可以將類的析構函式設定成私有的,當有人想要建立物件在棧上的時候就會失敗,因為作業系統找不到對應的析構函式(不要將建構函式也做成私有的,因為建立物件在堆上的時候也要呼叫建構函式的,除非想要做成單例的樣子)。這樣只能去new物件到堆上了,但是由於析構函式是私有的,程式設計師仍然需要自己設定析構功能的函式,並記得呼叫,防止出現記憶體洩漏的情況。下面是例子,值得注意的是,構造和析構函式被設定成了protected的,是為了能夠正常的繼承。create函式被設定成static的是為解決外部無法發現建構函式,需要有乙個可以被外部訪問到的介面去呼叫。

class a

~a(){}

public:

static a* create()

void destory()

};

如果想讓物件只能在棧上,那就是不能讓別人使用到new這個操作符。可以在class中過載了私有的成員函式new,而且delete也需要一起過載下。如下面的例子:

class a

// 注意函式的第乙個引數和返回值都是固定的

void operator delete(void* ptr){} // 過載了new就需要過載delete

public:

a(){}

~a(){}

};

只在堆或棧上生成物件

一般情況下,編寫乙個類,是可以在棧或者堆分配空間。但有些時候,你想編寫乙個只能在棧或者只能在堆上面分配空間的類。這能不能實現呢?仔細想想,其實也是可以滴。在c 中,類的物件建立分為兩種,一種是靜態建立,如a a 另一種是動態建立,如a ptr new a 這兩種方式是有區別的。1 靜態建立類物件 是...

如何只在堆或者棧上分配類物件

2015 08 13 13 42 315人閱讀收藏 舉報 c c 61 昨天乙個同學去網易面試c 研發,問到了這麼乙個問題 如何限制乙個類物件只在棧 堆 上分配空間?一般情況下,編寫乙個類,是可以在棧或者堆分配空間。但有些時候,你想編寫乙個只能在棧或者只能在堆上面分配空間的類。這能不能實現呢?仔細想...

C 如何只在堆 棧上建立類的物件

建構函式私有化 將類的建構函式私有,拷貝構造宣告成私有。防止別人呼叫拷貝在棧上生成物件。提供乙個靜態的成員函式,在該靜態成員函式中完成堆物件的建立。class heap only priivate c 98 類的構造和拷貝構造只宣告不定義a a const a c 11下的新寫法a delete a...