国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

淺談多態中的虛函數和虛表

2019-11-08 18:40:06
字體:
來源:轉載
供稿:網友

需要實現多態必不可少的就是虛函數,類的成員函數前加virtual關鍵字,這個成員函數就是虛函數;例如:

class T{	public:		virtual void fun()	{		cout<<"fun()"<<endl;	}		int _t;};在不加virtual的情況下:sizeof(T)的大小為4;加了vitual變成虛函數之后:sizeof(T)的大小為8;這是為什么呢??   存在虛函數的類的對象模型為:

由此圖可以看出T的對象中不僅有_t而且還有一個指針,這個指針指向的是一個存放虛函數地址的表,也就是虛表。所以在類成員函數前加了virtual之后的大小為8;根據下圖就可以看出虛表中是怎么去存放虛函數的地址:

在單繼承下的虛函數表又是什么樣??

class T{public:	  virtual void fun1()	{		cout << "T::fun1()" << endl;	}	 virtual  void fun2()	  {		  cout << "T::fun1()" << endl;	  }	int _t;};class Z : public T{public:	virtual void fun1()	{		cout << "Z::fun1" << endl;	}	virtual void fun3()	{		cout << "Z::fun3" << endl;	}	int _z;};上述代碼中,類Z單繼承T,重寫了T類中的fun1,fun2并沒有重寫,在Z類本身中還加了自己的虛函數fun3;Z的對象模型為:

vs2013監視窗口:

由上圖監視窗口可以看出在__vfPtr所指的虛表中只有Z::fun1和T::fun2這兩個虛函數的地址,fun3并沒有存在于虛表中,這是因為vs2013下編譯器的一個bug,不過我們換一種方式(打印虛表)來看虛表:

class T{public:	  virtual void fun1()	{		cout << "T::fun1()" << endl;	}	 virtual  void fun2()	  {		  cout << "T::fun1()" << endl;	  }	int _t;};class Z : public T{public:	virtual void fun1()	{		cout << "Z::fun1()" << endl;	}	virtual void fun3()	{		cout << "Z::fun3()" << endl;	}	int _z;};typedef void (*V_F) ();void PRintVtable(int vptr){	int * ptr = (int *)vptr;	printf("虛表:0x%p/n",ptr);	for (int i = 0; ptr[i] != 0; i++) //通常虛表以0為結束標志;	{		V_F f = (V_F)ptr[i];		f();	}}void test(){	Z z;	PrintVtable(*(int*)(&z));}運行截圖:

多繼承的虛函數表:

class T{public:	  virtual void fun1()	{		cout << "T::fun1()" << endl;	}	 virtual  void fun2()	  {		  cout << "T::fun2()" << endl;	  }	int _t;};class Z {public:	virtual void fun1()	{		cout << "Z::fun1()" << endl;	}	virtual void fun2()	{		cout << "Z::fun2()" << endl;	}	int _z;};class P : public Z,public T{public:	virtual void fun1()	{		cout << "P::fun1()" << endl;	}	virtual void fun3()	{		cout << "P::fun3()" << endl;	}};typedef void (*V_F) ();void PrintVtable(int vptr){	int * ptr = (int *)vptr;	printf("虛表:0x%p/n",ptr);	for (int i = 0; ptr[i] != 0; i++) //通常虛表以0為結束標志;	{		V_F f = (V_F)ptr[i];		f();	}}void test(){		P p;	PrintVtable(*(int *)(&p));}運行截圖:

可以看出在虛函數表中沒有出現虛函數T::fun2();這是因為派生類中的虛函數會放在第一個繼承的虛表中;


上一篇:(十一)狀態模式

下一篇:Groovy集合Map

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 建水县| 卢氏县| 大余县| 达州市| 鹤峰县| 景洪市| 始兴县| 安义县| 松滋市| 斗六市| 嘉荫县| 西林县| 云霄县| 铁岭市| 保靖县| 林州市| 永吉县| 扬州市| 寿宁县| 穆棱市| 丰宁| 壤塘县| 彝良县| 南澳县| 海阳市| 馆陶县| 泰兴市| 五原县| 鄂伦春自治旗| 富源县| 嫩江县| 黑水县| 沅江市| 安顺市| 祁阳县| 广昌县| 嘉义县| 南靖县| 锡林浩特市| 栾城县| 镇康县|