日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

C++深度探索虛函數指針示例_C 語言

作者:Huuaaaaa ? 更新時間: 2023-01-19 編程語言

代碼描述:定義一個Person類為基類,ChinesePer 類與EnglishPer類都繼承于此基類。

class Person
{
public:
	void speak() {
		cout << "說人話" << endl;
	}
private:
	int m_type = 1 ;
};
class ChinesePer :public Person {
public:
	void speak() {
		cout << "說中國話chinese..." << endl;
	}
};
class EnglishPer :public Person {
public:
	void speak() {
		cout << "說英國話english..." << endl;
	}
};

先看看此時各個類占用的內存信息:

int main() {
	int person_size = sizeof(Person);
	int Chineseper_size = sizeof(ChinesePer);
	int Englishper = sizeof(EnglishPer);
}

可以看到三個類的大小都為4個字節,占用的情況就是 類中的m_type變量。

將基類中的 speak() 函數加上virtual關鍵字 ,成為虛函數后再次查看內存字節大小:

可以看到多出了4個字節大小的空間(X86),三個類的大小都為 8。其實就是多出了一個指針的大小,4個字節 ,創建一個子類對象就可以明顯看出來:

可以得出結論一:繼承過來的成員變量 m_type(4個字節) + _vfptr(4個字節) = 8個字節。

繼續探索虛函數表的原理, 創建以下子類對象并通過父類指針指向子類對象調用speak函數發生多態:

int main(){
	ChinesePer chs;
	ChinesePer chs2;
	EnglishPer eng;
    Person *ptr = &chs;		//父類指針指向子類對象
	Person *ptr1 = &chs2;
	Person *ptr2 = &eng;
	ptr->speak();
	ptr1->speak();
	ptr2->speak();
}

以上代碼執行后會發生多態:

此時我們看看三個對象的內存分布:

用圖片簡要描述一下就是:

在這里可以先得到結論二: 同一個子類的所有對象共享一個虛函數表,指向虛函數表的指針_vptr是相同的。

在內存分布上查看一下 eng對象的虛函數指針地址情況:

可以看到該虛函數指針的地址上的值,存放的正是 該子類中的重寫函數 speak()函數的地址。

如果把這個地址的值,修改為 Chineseper 類中的重寫函數speak() 的地址值,會發生什么?

手動修改了eng對象中虛函數指針內的地址值,將改值本來是存放的是 EnglishPer 類中的speak() 函數的地址,現在更改為 ChinesePer 類中speak() 函數的地址。

單步走發生多態:

至此可以得出結論三:

當基類函數加了virtual 關鍵字后,虛函數的調用方法是間接調用:先查虛函數表的地址(也就是指向虛函數表的指針 _vptr),再查虛函數表中的虛函數指針。

不妨在基類繼續添加兩個虛函數

class Person
{
public:
	virtual void speak() {
		cout << "說人話" << endl;
	}
	virtual void eat() {
		cout << "吃飯" << endl;
	}
	virtual void sleep() {
		cout << "睡覺" << endl;
	}
private:
	int m_type =1 ;
};

子類只重寫了speak函數,查看一下chs對象的虛函數指針地址存放的值:

的確存放的還是各個函數的地址,且是連續存放的,因此在進行查表調用虛函數的時候,也是每移動4個字節指向的就是一個函數的指針地址。

可以簡要描述一下形式就很直觀了:

總結:

1.增加了virtual 關鍵字的對象頭部4個字節是一個指針,指向了虛函數表的地址(單繼承情況下)。

2.同一個子類的所有對象共享一個虛函數表,指向虛函數表的指針_vptr是相同的。

3.當基類函數加了virtual 關鍵字后,虛函數的調用方法是間接調用:先查虛函數表的地址(也就是指向虛函數表的指針 _vptr),再查虛函數表中的虛函數指針。

原文鏈接:https://blog.csdn.net/Huuaaaaa/article/details/128265524

欄目分類
最近更新