虚函数原理1

部分参考:http://blog.csdn.net/devilkin64/article/details/5939613

虚函数表的建立是取决于定义类的时候是否包含虚函数,如果有类函数/ 方法声明为虚,则改类会建立一张虚表.在网上找到一个牛人用汇编的方法论证虚 表是存放在常量区内(具体论证就省略,否则就扯远了). 继承类会同样建立一张虚表,并将覆盖虚表中父类虚函数的地址.
在编译阶段,编译器为每个包含虚函数的类创建一个虚表,这个类的所有对象中的虚表指针,都指向这同一份虚表;一般虚表指针放在对象的开始位置;
虚函数表是在代码编译生成,程序载入内存的时候,放在内存常量区. 
虚函数指针是在对象建立时由构造函数生成并保存于对象地 址首部.
虚函数指针:虚函数指针是在实例化对象 的时候由构造函数生成的指向虚表的指针.放在对象地址的首位. 下面代码用于显 示虚表及虚表指针.

class base
{
public:	
	int a;
	virtual void Print()
	{
		cout<<"in base print\n";
	}
};

class d1:public base
{
public:
	void Print()
	{
		cout<<"in d1 print\n";
	}

	void d1Print()

	{
		cout<<"d1 self print \n";
	}
};

class d2:public d1
{
public:
	void Print()
	{
		cout<<"in d2 print\n";
	}
	void d2Print()
	{
		cout<<"d2 self print \n";
	}
};

typedef void (*pfun)();

int main()
{
	
	base *md2 = new d2;
	md2->Print();

	d1 *md1 = new d2;
	md1->Print();
	//上面两个例子说明,虚函数具有向下传递的特性;只要在最开始的基类中定义虚函数,则其他所有的子孙类都默认是虚函数

	int *p2 =(int *) md2;//md2本来是指向对象的一个指针,将此指针转换为指向一个int数组的指针,这样就能像访问数组一样访问对象里面的数据
	cout<<*p2<<endl;//*p2是指放在对象md2中第一个位置的元素的值,这个值就是虚表的地址
	p2  =(int *)(*p2);//*p2是虚表的地址,也就是指虚表的指针,我们要把虚表也表示成数组的形式,把指向虚表的指针转换为指向一个Int数组的指针
	printf("%x\n",p2);//
	cout<<p2<<endl;//
	printf("%d\n",p2);//上面三个输出的值都是相等的,只不过是十进制或者十六进制表示的不同

	(pfun(*p2))();

	int *p1 = (int *) md1;
	cout<<*p1<<endl;//上面所有的输出都是显示的是类d2的虚表的地址,也就是说不管类有多少个对象,但是虚表只有一份

	/*int i =0;
	int *p = &i;
	cout<<&i<<" "<<p<<endl;*/

	delete md1;
	delete md2;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值