单一继承下虚函数覆盖时vftb的排列

#include <iostream>
#include <string>
#include <vector>
#include <cctype>
using namespace std;

//单一继承下有虚函数覆盖
//派生类只有一个虚函数表,派生类对象只有一个虚指针来指向这个虚函数表。
//虚函数表中按照基类虚函数(若派生类override基类的虚函数,则虚函数表中原先存放的基类虚函数的地址变为相应的派生的虚函数的地址)、派生类新增的虚函数顺序依次排列。



class Base
{
public:
	int x;
	virtual void f(){cout << "Base::f" << endl;}
	virtual void g(){cout << "Base::g" << endl;}
	virtual void h(){cout << "Base::h" << endl;}
};

class Derive:public Base
{
public:
	int y;
	virtual void f(){cout << "Derive::f" << endl;}
	virtual void g(){cout << "Derive::gg" << endl;}
	virtual void hh(){cout << "Derive::hh" << endl;}

};

typedef void (*Fun)();

int main()
{
	Fun pFun;

	Base base;
	void*** p = (void***)&base;
	cout<<*p<<endl;  // 虚函数表的地址

	cout<<(**p)<<endl;  //虚函数表中指向第一个虚函数的地址
	cout<<(*p)[1]<<endl;
	cout<<(*p)[2]<<endl;



	Derive derive;
	void*** q = (void***)&derive;  
     
   
	cout<<*q<<endl;  // 虚函数表的地址
	
	//由于derive类override基类的第一个虚函数f();此时派生类虚函数表中的第一项的内容为指向Derive类f()函数的地址
	cout<<(**q)<<endl;  //虚函数表中指向第一个虚函数的地址Derive::f(){}
    //cout<<(***q)<<endl; // !!!错误,提示表达式必须是指向完整类型的指针,q为void之故
	
	//对象运行时类型识别的指针 ,存放在vptr-1处的内存中
	//cout<<*((*q)-1)<<endl;  //

	//下面两种表示方式意义相同
	//cout<<*((*q)+1)<<endl; //虚函数表中指向第2个虚函数的地址,derive类override基类的第一个虚函数g()
	cout<<(*q)[1]<<endl; //指向第一个虚函数的地址Derive::g(){}

	//cout<<*((*q)+2)<<endl; //虚函数表中指向第3个虚函数的地址,由于没有覆盖,指向基类的第3个虚函数Base::h()
	cout<<(*q)[2]<<endl;

	//cout<<*((*q)+3)<<endl; //虚函数表中指向第4个虚函数的地址;指向派生类新增的虚函数Derive::hh()
	cout<<(*q)[3]<<endl; 

	//cout<<*((*q)+4)<<endl; //虚函数表中指向第5个虚函数的地址;由于不存在第五个虚函数,输出结果地址是空。
	cout<<(*q)[4]<<endl;    

	pFun = (Fun)(**q);
	pFun();
	pFun = (Fun)((*q)[1]);
	pFun();
	pFun = (Fun)((*q)[2]);
	pFun();
	pFun = (Fun)((*q)[3]);
	pFun();


	system("pause");
	return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值