1. 程式人生 > >C++虛擬函式物件模型剖析

C++虛擬函式物件模型剖析

測試環境:VS2013

C++中的類物件模型有簡單的,也有複雜的。今天嘗試著剖析一下,以加深對繼承,虛擬函式等的理解。

從最簡單的繼承開始

class Base
{
public:
	int b;
};

class Derive : public Base
{
public:
	int d;
};

int main()
{
    cout << sizeof(Derive) << endl;
	Derive d1;
	d1.b = 0x01;
	d1.d = 0x02;
	return 0;
}

定義一個基類Base類,將其成員變數設為公有,為了方便修改。定義一個派生類Derive類,繼承自Base類。在main中輸出派生類的大小,建立一個Derive類物件,對它的成員資料分別賦值以方便在記憶體中進行區分。執行程式輸出8 個位元組,我們可以依據這個數值通過&d1將記憶體中的d1截取出來:

                 

可以看出d1的物件模型:

                

這個就作為練手。剩下的說的就不那麼詳細了。

繼承+虛擬函式

class Base
{
public:
	virtual void fun1(){}
	virtual void fun2(){}
public:
	int b;
};

class Derive : public Base
{
public:
	virtual void fun1(){}
	virtual void fun2(){}
	virtual void fun3(){}
public:
	int d;
};

int main()
{
	cout << sizeof(Derive) << endl;
	Derive d1;
	d1.b = 0x01;
	d1.d = 0x02;

	return 0;
}
輸出12:

                  

虛擬函式+多重繼承

class Base
{
public:
	virtual void fun1()
	{
		cout << "Base::fun1()" << endl;
	}
	virtual void fun2()
	{
		cout << "Base::fun2()" << endl;
	}
public:
	int b;
};

class C : public Base
{
public:
	virtual void fun1()
	{
		cout << "C::fun1()" << endl;
	}
public:
	int c;
};

class Derive : public C
{
public:
	virtual void fun2()
	{
		cout << "Derive::fun2()" << endl;
	}
	virtual void fun3()
	{
		cout << "Derive::fun3()" << endl;
	}

public:
	int d;
};

int main()
{
	cout << sizeof(Derive) << endl;
	Derive d1;
	d1.b = 0x01;
	d1.c = 0x0c;
	d1.d = 0x02;
	d1.fun1();
	d1.fun2();
	d1.fun3();

	return 0;
}

輸出16:

                 

菱形繼承+虛擬函式

class Base
{
public:
	virtual void fun0()
	{
		cout << "Base::fun0()" << endl;
	}
	virtual void fun1()
	{
		cout << "Base::fun1()" << endl;
	}
	virtual void fun2()
	{
		cout << "Base::fun2()" << endl;
	}
public:
	int b;
};

class C1 : public Base
{
public:
	virtual void fun1()
	{
		cout << "C1::fun1()" << endl;
	}
public:
	int c;
};

class C2 : public Base
{
public:
	virtual void fun1()
	{
		cout << "C2::fun1()" << endl;
	}
public:
	int c;
};

class Derive : public C1, public C2
{
public:
	virtual void fun2()
	{
		cout << "Derive::fun2()" << endl;
	}
	virtual void fun3()
	{
		cout << "Derive::fun3()" << endl;
	}

public:
	int d;
};

int main()
{
	cout << sizeof(Derive) << endl;
	Derive d1;
	d1.C1::b = 0x01;
	d1.C1::c = 0x1c;
	d1.C2::b = 0x01;
	d1.C2::c = 0x2c;
	d1.d = 0x02;

	d1.C1::fun0();
	d1.C1::fun1();
	d1.C1::fun2();

	d1.C2::fun0();
	d1.C2::fun1();
	d1.C2::fun2();

	d1.fun3();

	return 0;
}