(C++对象模型):多重继承第二基类对虚函数支持的影响(thunk作用)及虚继承下的虚函数

多重继承第二基类对虚函数支持的影响(this指针调整作用)

  • 子类继承了几个父类,子类就有几个虚函数表

class Base
{
public:
	virtual void f() { cout << "Base::f()" << endl; }
	virtual void g() { cout << "Base::g()" << endl; }
	virtual void h() { cout << "Base::h()" << endl; }	
 
	virtual ~Base() {
		int abc;
		abc = 1;
	}
 
};
 
class Base2
{
public:
	virtual void hBase2() {
 
		cout << "Base2::hBase2()" << endl;
	}
 
	virtual ~Base2()	{
		int abc;
		abc = 1;
	}
};
 
class Derive :public Base,public Base2 {
public:
	virtual void i() { cout << "Derive::i()" << endl; }
	virtual void g() { cout << "Derive::g()" << endl; }
	void myselffunc() {} //只属于Derive的函数
 
	virtual ~Derive() {
		int abc;
		abc = 1;
	}	
};
  • 多重继承下,有几种情况,第二个或者后续的基类会对虚函数的支持产生影响
  • this指针调整,调整的目的是干什么?
    • this指针调整的目的就是让对象指针正确的指向对象首地址,从而能正确的调用对象的成员函数或者说正确确定数据成员的存储位置。
  • a)通过指向第二个基类的指针调用继承类的虚函数(thunk)
Base2 *pb2 = new Derive();
delete pb2; //调用继承类的虚析构函数
  • b)一个指向派生类的指针,调用第二个基类中的虚函数
Derive *pd2 = new Derive();
pd2->hBase2();
  • c)允许虚函数的返回值类型有所变化
class Base
{
public:
	virtual void f() { cout << "Base::f()" << endl; }
	virtual void g() { cout << "Base::g()" << endl; }
	virtual void h() { cout << "Base::h()" << endl; }	

	virtual ~Base() {
		
	}

	virtual Base *clone() const
	{
		return new Base();
	}

};

class Base2
{
public:
	virtual void hBase2() {

		cout << "Base2::hBase2()" << endl;
	}

	virtual ~Base2()	{
	
	}

	virtual Base2 *clone() const
	{
		return new Base2();
	}
};

class Derive :public Base,public Base2 {
public:
	virtual void i() { cout << "Derive::i()" << endl; }
	virtual void g() { cout << "Derive::g()" << endl; }
	void myselffunc() {} //只属于Derive的函数

	virtual ~Derive() {
		
	}	
	virtual Derive *clone() const
	{
		return new Derive();
	}
};

int main()
{	
    Base2 *pb1 = new Derive(); //pb1指向的是Base2子对象的首地址
    Base2 *pb2 = pb1->clone(); //Derive::clone();

    return 0;
}

  • 执行clone()时,pb1首先会调整回指向Derivce对象的首地址,这样调用的是Derive版本的clone()。

虚继承下的虚函数

class Base
{
public:
	virtual void f() {}
	virtual ~Base() {}
	int m_basei;
};

class Derive :public virtual Base
{
public:
	virtual ~Derive(){}
	int m_derivei;
};

int main()
{	
cout << sizeof(Derive) << endl;  //16
Derive dobj;
dobj.m_basei = 2;
dobj.m_derivei = 5;

Derive *pdobj = new Derive();
pdobj->f();

return 0;
}
  • 调试

  • 结构

...

Derive *pderive = new Derive();
Base *pbase2 = (Base *)pderive;
pbase2->m_basei = 7;

...
  • 通过调试查看地址,得出如下结构

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值