物件的儲存空間 虛析構函式

2021-09-02 22:47:31 字數 3476 閱讀 2309

在實際了解物件的儲存空間之前,相信大家也或多或少在某些地方看到過介紹有關乙個物件的儲存空間有多大,但有沒有深入去了解關於乙個物件為什麼需要這麼大的記憶體空間?到底是什麼導致乙個物件佔了這麼大的記憶體空間?

讓我們通過幾個簡單的例子來先了解一下乙個物件所占用的記憶體空間

空類儲存空間的計算:

#include

using namespace std;

class test

;int

main()

得到結果(執行環境:ubuntu 18.04, gcc 7.3.0):

上述定義了乙個空類,沒有任何成員,得到結果為1;空型別物件不包含任何資訊,大小應該為0,但當我們宣告了該型別的物件時,它必須在記憶體中占有一定的空間,否則無法使用這些物件。至於占用多少記憶體,由編譯器決定

只有成員變數的類的計算:

#include

using namespace std;

class test

;int

main()

得到結果(執行環境:ubuntu 18.04, gcc 7.3.0):

這個應該很清楚,類中有3個int型變數,所以佔12bytes,那麼靜態成員變數呢?

有成員變數及靜態成員變數的計算:

#include

using namespace std;

class test

;int

main()

得到結果(執行環境:ubuntu 18.04, gcc 7.3.0):

這個結果與上述不加靜態成員變數一致,所以得出靜態成員變數不佔記憶體空間

類中只有乙個成員函式的儲存空間計算:

#include

using namespace std;

class test

;int

main()

得到結果(執行環境:ubuntu 18.04, gcc 7.3.0):

這個結果與空類是一致的,所以得出成員函式是不佔記憶體空間的

類中建構函式、析構函式的空間占用情況:

#include

using namespace std;

class test ;~

test()

;};int

main()

得到結果(執行環境:ubuntu 18.04, gcc 7.3.0):

與空類物件一致,得出建構函式與析構函式也是不佔空間的

類中含有虛析構函式:

#include

using namespace std;

class test

; virtual ~

test()

;};int

main()

得到結果(執行環境:ubuntu 18.04, gcc 7.3.0):

類中含有乙個構造與乙個虛析構函式,得出結果為8。由上述可知建構函式不佔記憶體空間,那麼便是由虛析構函式占用了8bytes的記憶體

繼承空類與多重繼承空類儲存空間的計算:

#include

using namespace std;

class test

;class b

;class c : public test

;class d : public virtual b

;class e : public test, public b

;int

main()

得到結果(執行環境:ubuntu 18.04, gcc 7.3.0):

從上面結果可知,單一繼承的空類空間為1,多重繼承的空類空間為1,但虛繼承得到的空類空間為8bytes

由此得出:每個物件所占用的儲存空間只是該物件的非靜態資料成員的總和

今天在看書的時候發現了自己不太清楚的乙個盲區,就是有關虛析構函式,而且涉及到記憶體洩漏問題,所以就在這裡提一下

書中提到:當派生類物件經由乙個基類指標被刪除,而該基類帶著乙個non-virtual析構函式,會導致物件的派生類部分沒被銷毀掉,從而造成記憶體洩漏

以下舉個例子來說明該問題:

#include

using namespace std;

class base

~base()

};

class derive: public base

~derive()

};intmain()

得到結果(執行環境:ubuntu 18.04, gcc 7.3.0):

從所得結果來看,析構函式只做了區域性銷毀工作,這可能形成資源洩漏、損壞資料結構等問題,那麼怎樣解決呢?

很簡單,將基類的析構函式宣告為虛函式,利用多型的性質實現將兩個都析構

將上述**中base的析構函式改為虛函式,得到執行結果:

物件的記憶體空間大小

虛析構函式

-----------------------------------------19.1.23日-----------------------------------------

牛客網習題:

#include

using namespace std;

class test

test

(int temp1 =0,

int temp2 =0)

intgeta()

intgetb()

};intmain()

這種情況下應優先考慮虛表的儲存位址,像在該題中,首先交換的是虛表的指標,其次交換a的值,由此分析可以得到a

=200,b

=10a = 200, b = 10

a=200,

b=10

測試(64位機,sub

C 虛析構函式 純虛析構函式

虛析構函式 析構函式的工作方式是 最底層的派生類 most derived class 的析構函式最先被呼叫,然後呼叫每乙個基類的析構函式。因為在c 中,當乙個派生類物件通過使用乙個基類指標刪除,而這個基類有乙個非虛的析構函式,則結果是未定義的。執行時比較有代表性的後果是物件的派生部分不會被銷毀。然...

C 虛析構函式 純虛析構函式

虛析構函式 析構函式的工作方式是 最底層的派生類 most derived class 的析構函式最先被呼叫,然後呼叫每乙個基類的析構函式。因為在c 中,當乙個派生類物件通過使用乙個基類指標刪除,而這個基類有乙個非虛的析構函式,則結果是未定義的。執行時比較有代表性的後果是物件的派生部分不會被銷毀。然...

C 虛析構函式 純虛析構函式

虛析構函式 析構函式的工作方式是 最底層的派生類 most derived class 的析構函式最先被呼叫,然後呼叫每乙個基類的析構函式。因為在c 中,當乙個派生類物件通過使用乙個基類指標刪除,而這個基類有乙個非虛的析構函式,則結果是未定義的。執行時比較有代表性的後果是物件的派生部分不會被銷毀。然...