C++虛擬繼承例子

代碼如下:

#include<iostream>
using namespace std;
class Base {
public: 
	void fun(){cout<<"Base::fun"<<endl;}
    virtual void f() { cout << "Base::f" << endl; }
    virtual void g() { cout << "Base::g" << endl; }
    virtual void h() { cout << "Base::h" << endl; }
	int a;
	int b;
};

class Base2:virtual public Base
{
public: 
	virtual void fun2(){cout<<"Base2::fun2"<<endl;}
    virtual void f() { cout << "Base2::f" << endl; }
    virtual void g() { cout << "Base2::g" << endl; }
    virtual void h() { cout << "Base2::h" << endl; }
	int a;
	int b;
};

class Base3:virtual public Base
{
public: 
	virtual void fun3(){cout<<"Base3::fun3"<<endl;}
    virtual void f() { cout << "Base3::f" << endl; }
    virtual void g() { cout << "Base3::g" << endl; }
    virtual void h() { cout << "Base3::h" << endl; }
	int a;
	int b;
};


class Derive: public Base2,public Base3
{
public: 
	//注意:如果Base2和Base3都是從Base繼承,且都重寫了Base的函數f,則Derive類必須要重寫函數f,否則
	//在調用的時候會引起歧義,導致出錯。因此這樣編譯時不通過的。
    virtual void f() { cout << "Derive::f1" << endl; }
    virtual void g() { cout << "Derive::g1" << endl; }
    virtual void h() { cout << "Derive::h1" << endl; }
	virtual void fun(){ cout << "Derive::fun" << endl; }
	int c;
	int d;
};

int main()
{	
	typedef void(*Fun)(void);
	Fun pFun = NULL;
	
	Derive b;
  
 	cout<<"&b.Base::a="<<&b.Base::a<<endl;
	cout<<"&b.Base::b="<<&b.Base::b<<endl;
	cout<<"&b.c="<<&b.c<<endl;
	cout<<"&b.d="<<&b.d<<endl;
	cout<<"&b.Base2::a="<<&b.Base2::a<<endl;
	cout<<"&b.Base2::b="<<&b.Base2::b<<endl;
	cout<<"&b.Base3::a="<<&b.Base3::a<<endl;
	cout<<"&b.Base3::b="<<&b.Base3::b<<endl;
    cout << "Base2的虛函數表地址:" << (&b) << endl;
    cout << "Base2的虛函數表 — 第一個函數地址:" << *(int*)(&b) << endl;
	cout << "Base2的虛基類地址:" << *((int*)(&b)+1) << endl;
	cout<<sizeof(b)<<endl;

	pFun=(Fun)*((int*)*(int*)(&b));//Base2的虛函數
	pFun();
	pFun=(Fun)*((int*)*(int*)(&b)+1);//Derive的虛函數,注意Derive虛函數是在Base2的虛函數後面,
									 //兩者共享一個虛函數指針,如果Base2沒有除了基類以外的虛函數
									 //那這個指針就只有Derive的虛函數,如果Derive也沒有除了基類
									 //以外的虛函數,就不存在這個虛函數指針了
	pFun();

	pFun=(Fun)*((int*)*((int*)&b+4));//Base3的虛函數,同上面一樣,如果Base3中除了基類的虛函數外沒有其他
									 //虛函數,則不存在這個虛函數指針,所有的虛函數都到虛基類中的虛函數
									 //去尋找和執行
	pFun();

	cout<<*((int*)(&b)+1)<<endl;//Base2的虛基類指針
	cout<<*((int*)(&b)+5)<<endl;//Base3的虛基類指針
	cout<<*((int*)*((int*)&b+1)+1)<<endl;//虛基類距離當前Base2的偏移量,單位是字節
	cout<<*((int*)*((int*)&b+5)+1)<<endl;//虛基類距離當前Base3的偏移量,單位是字節

	system("pause");
	return 0;
}
運行結果如下所示:


內存分佈如下所示:




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章