1 这一节主要讨论虚函数,以及关于继承问题。
在C++中,多态表示以一个基类指针或者引用,寻址出一个派生类对象
例如: point *ptr; ptr=new point2D; ptr=new point3D;
假设z() 是point 类的一个虚函数 有 ptr->z();
我们要想准确调用z(),需要两个条件 1 ptr所指的对象(point 或者是point2D 或者point3D) 2 知道对象了还需要知道其位置,才能调用
一个class只会有一个virtual table,每个table 里面包含着该类对应的虚函数。
虚函数的地址是可以在编译器时期获知,一旦生成就不会改变。
1 为了找到表格 ,每个object 被编译器安插了一个指向表格 的指针
2 为了找到函数,在表格里面有每个虚函数对应的表格索引。
当虚函数表碰到单一继承————————》》》》》》》多态
继承的类对应的虚函数表和基类的虚函数表是对应的,变化的是对应的函数类型。基类的是point 派生类的是point2D 但是函数名是一样的(除了析构函数)
所以在编译时期可以得到(*ptr->vptr[dex](PTR))
剩下就是坐等执行期的指针对象了。
当虚函数碰到多继承——————————》》》》》》》多态
多重继承的问题在于第二个基类了
1 原先的一种解决办法是给虚函数表添加信息及表的每个索引点不仅仅只是个指针还包含可能的offset(偏移量),但是这产生一个问题,针对base class 1 的函数不需要offset。
2 Thunk技术(自己百度一下)的引进(1 以适当的offset值调整this指针,2 跳到virtual funtion 去)解决了上面某些函数不必要offset.
3 有n个baseclass编译器会产生n个表,每个表有一个对应的指针,最左边的主表,与base1 共享,其它的为次表 与basei(i=2 ……)相关
当指针对象为base1 或者派生类则调用的为主表,当指针指向的是base2 则调用的次表。
4 后来sun编译器将多个虚表连锁为一个,指向此表的指针可以通过主表加上offset获得。则每个class 只含有一个具名的虚表。