c++中的虚函数表测试(关于类的动态调用和静态调用)

虚函数表的百度解释如下:

类的虚函数表是一块连续的内存,每个内存单元中记录一个JMP指令的地址

  注意的是,编译器会为每个有虚函数的类创建一个虚函数表,该虚函数表将被该类的所有对象共享。类的每个虚成员占据虚函数表中的一行。如果类中有N个虚函数,那么其虚函数表将有N*4字节的大小。

 

一个类只要有虚函数,其就会有有一个虚函数表指针,通过指针,编译器可以找到对应的虚函数地址。具体说明见下面的网址

http://apps.hi.baidu.com/share/detail/10397448

 

此处我想通过一个实验来加强对编译器使用虚函数表的理解。讨论帖见下面的地址

http://topic.csdn.net/u/20100714/14/1bf1685b-eeed-4562-9836-7291a61f8315.html?seed=1792954863&r=66962110#r_66962110

 

我设计两个类,一个基类和它的派生类,两个类都只有一个虚函数。在百度上查到“类的虚函数表是一块连续的内存,每个内存单元中记录一个JMP指令的地址”。因此我想,如果我将派生类对象覆盖了基类对象,是否会把基类的虚函数表指针更改呢?

测试的代码如下:

 

有兴趣的可以运行一下。
输出显示a的this指针保存的内容的确发生了变化,但是其仍能寻找的a的print函数。这让我对虚函数表指针产生了疑惑,这个指针明明指向的是b的虚函数表,为啥没有调用b的print函数呢?编译器是如何做到这一点的?

 

后来使用A *p=&a;p->print();发现此时调用的是B的打印函数。

 

关于这个疑惑,一个牛人(飞雪)的解释是,多态的条件不满足,意思是只有指针或引用才能产生多态,也就是说p是指针,编译器会进行多态性检测(检查虚函数表)。而a.print()不是指针或引用,并不满足多态条件,那a.print()编译器是如何查找函数地址的呢?这个问题没有人告诉我,还需要等待。。。

 

经过讨论帖里的回复,终于明白了编译器的调用原则:静态调用和动态调用

 

a.print()   等价于 a.A::print(); 此处是静态调用,因此此时不会经过虚函数表

 

p->print() 等价于 a.B::print();此处是动态调用,因此需要查询虚函数表

 

后来我又做了一个实验加深理解,将B类空间的打印去掉,声明一个C类继承B类,如上述操作后,调用b.print(),我想此处B::print是不存在的,它是否会去找虚函数表呢?证明结果不会,因此静态调用应该是当B类空间找不到时,会到B类的基类中寻找,即b.B::A::print()。只有动态调用才会找虚函数表,而满足动态调用的条件是指针或引用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值