多虚函数表指针的一点困惑
http://blog.csdn.net/hairetz/article/details/4137000
但是,我始终有这样的问题,在该帖子的第一张图中,(事先声明, 整篇帖子都是非虚拟继承)编译器根本就没必要维护一张虚函数表,因为在继承的类层次结构上看,先从base的角度看,他自己的函数,无论是vir还是非vir函数,都应当统统当做普通成员函数来对待,因为自己的虚函数,对自己是没有多态的,一个类所声明的虚函数,语义上,是表明在他的子类中才会表现出多态,因此,只有必要在子类中维护虚表以提供多态机制即可,而没有必要画蛇添足,在父类中为自己的虚函数添加虚表,你能解释,在父类中,为自己的虚函数添加虚表的目的是什么吗?语义上表明什么?难道自己调用自己的函数,还要几步跳转,这既浪费空间,又浪费效率。
我始终认为,从类的层次结构上看, 以及从虚函数的语义上看,一个类,没有必要为自己的虚函数维护虚表,统统当做普通成员函数对待,只需要在派生类中维护虚表,因为前面已经提到过,一个类的虚函数不是给自己表达多态的语义的,而是给派生类表达多态的语义,因此,就只需要派生类中提供虚表即可。
但是,好多的博文中,都出现了这种情况,一旦一个类有虚函数,那么这个类就会产生一枚虚表指针,指向这些虚函数,如果这真是事实,那么原因,到底是编译器为了追求简单,对虚函数采取统一处理?还是,编译器都不理解虚函数语义上是在哪一个类层次上才会表现出多态。
希望有兴趣的讨论一下
相关推荐
C++虚函数表与虚指针[项目源码]
本文详细介绍了C++中虚函数表(vtable)和虚指针(vptr)的概念及其在多态实现中的核心作用。虚函数表是编译器为包含虚函数的类生成的函数指针数组,用于存储虚函数地址;虚指针则是对象内部指向虚函数表的隐藏指针。文章通过示例代码和内存布局示意图,解释了虚函数表的继承与重写机制、虚指针的初始化与调用流程,以及多继承和虚继承下的特殊情况。此外,还强调了将析构函数设为虚函数的重要性,以避免内存泄漏问题。
C++中的虚函数表图解
C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。
(转)多重继承下的虚函数表
多态是C++语言中的一项重要的机制,虚函数就是为实现多态而设计的。多态就是用父类型的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”。而虚函数表在这种多态机制中起了核心调度的作用。由于是编译器在后台操作,所以它被蒙上了一层神秘的面纱。 对C++ 了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的。简称为VFTable。 在这个表中,主要是一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证其容真实反应实际的函数。这样,在有虚函数的类的实例中这个表被分配在了这个实例的内存中,所以,当我们用父类的指针来操作一个子类的时候,VFTable就显得尤为重要了,它就像一个地图一样,指明了实际所应该调用的函数。在C++的标准中提到,编译器必需要保证虚函数表的指针存在于对象实例中最前面的位置。 这意味着我们通过对象实例的地址得到它的VFTable,然后就可以遍历其中函数指针,并调用相应的函数。
指针的一些分析,解决初学者对指针的困惑
要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区。让我们分别说明。
C++虚函数表实例分析
多态是C++面向对象程序设计的一个重要特性。以前看到虚函数觉得很神奇,为什么就能实现多态了呢。最初的时候曾设想,要实现运行时多态,应该让对象的某个部分始终指向一个固定的地址,子类继承的时候,就修改这个地址的内容。这样,父类和子类都是到同一个固定地址去读取内容,在运行时就能表现不同行为。 在看了《深度探索c++对象模型》之后,发现思路是类似的。在对象中,有一个指针指向一张虚函数表,里面按照次序存放了每一个虚函数,当子类继承的时候,即到虚函数表的指定位置去修改函数地址。当我们通过父类指针来操作一个子类的时候,调用虚函数,都是通过虚函数表+固定的偏移,这样运行期多态便实现了。 在深度《深度》这本书中


