C 類幾種情況的記憶體布局

2021-08-09 10:22:19 字數 2639 閱讀 1562

對於c++開發者來說,了解其記憶體是非常必要的,同時c++的多型(動態繫結)的原理也是很重要的。

c++記憶體布局:

需要了解的幾種情況:

1、無虛函式,非繼承;

class ****** ;

void ******_fun2() {};

private:

int ******_a_;

};

記憶體布局:

沒有虛函式,沒有繼承,所以只有成員變數需要分配空間。

2、有虛函式,非繼承;

class base 

virtual void func2()

virtual void func3()

private:

int a_;

};

記憶體布局以及虛函式列表:

沒有繼承,有虛函式,所以有了虛函式列表vfptr,指向該類的虛函式列表,虛函式列表中記錄當前類的虛函式;

3、無虛函式,繼承;

class ******1 : public ****** ;

private:

int ******1_a_;

};

記憶體布局:

普通的繼承關係,而且基類中沒有虛函式,所以不會生成虛函式列表,指向基類的和指向自身類的指標是同乙個。

4、有虛函式,單繼承;

class derived : public base 

virtual void func4()

private:

int b_;

};

記憶體布局以及虛函式和列表:

單繼承中,基類有虛函式,所以首先是虛函式列表,然後是從基類繼承過來的成員變數,最後才是自己的成員變數。

由於override了基類的func2(),所以在虛函式列表中可以開看到,func2的域是derived,而不再是基類base。

5、有虛函式,多繼承(非虛擬繼承);

class derived2 : public base 

virtual void func5()

private:

int c_;

};class derived3 : public derived, public derived2

private:

int d_;

};

記憶體布局:

從以上記憶體布局可以發現一些問題,就是屬於base的成員變數a_出現了兩次,雖然生成的時候可以通過,但是在實際使用過程中容易造成二義性出錯,所以這種用法是需要盡量避免的。

虛函式列表:

虛函式列表中也有同樣的問題,兩個虛函式列表,有重複的函式base::func3(),在實際中也要盡量避免。

6、無虛函式,多繼承,虛擬繼承;

將以上的derived類和derived2類對base的繼承改為虛擬繼承:

class derived3 : public derived, public derived2 

private:

int d_;

};

記憶體布局:

最後一種情況使用了虛擬繼承,記憶體布局就不同了,可以看出,一共有5個虛函式列表,在第一部分中(0~8),由兩個虛函式列表和derived的成員變數b_,第乙個虛函式列表是derived3類繼承derived類時生成的,第二個虛函式是derived繼承時base生成的。

對於第二部分(12~20)同理,第三部分(24)則是derived3自己的成員變數;

第四部分(28~32),則是derived3間接繼承base生成的。

虛函式列表:

虛函式列表有點複雜,此處有點不明白,為什麼會有負數出現,隱約能夠看懂虛函式列表的指向。

從以上可以看到,在例項化乙個類物件的時候,僅僅為類的成員變數和虛函式列表指標分配空間(虛函式的情況下),而成員函式屬於整個類共有的,不會再物件中分配空間。因此,當虛函式更多的時候,占用的記憶體空間會更多,所以在實際專案中,關於類的繼承體系的設計,需要考慮到這個方面。

如有問題,還請指正。

C 記憶體洩漏的幾種情況

1.在類的建構函式和析構函式中沒有匹配的呼叫new和delete函式 兩種情況下會出現這種記憶體洩露 一是在堆裡建立了物件占用了記憶體,但是沒有顯示地釋放物件占用的記憶體 二是在類的建構函式中動態的分配了記憶體,但是在析構函式中沒有釋放記憶體或者沒有正確的釋放記憶體 2.沒有正確地清除巢狀的物件指標...

c 類的記憶體布局

本文基本上是對於stanley b.lippman的inside the c object model一書第一章第三章的概括,描述了c 類的記憶體布局情況.c 的類的記憶體布局有如下規則 1.nonstatic data member 存放在class object中 2.static data m...

c 類的記憶體布局

c 中的struct需要記憶體對齊,便於機器訪問該struct。每個物件 如果類含有虛函式 在首位址位置放置了vptr,指向自己的虛函式表。物件中不包含成員函式 靜態的或非靜態的 它們可以被物件共享,靜態成員函式沒有this指標,所以不能被物件呼叫,non static 成員函式隱含有乙個this指...