您的位置:首页 > 编程语言 > C语言/C++

C++多态的本质

2016-04-05 12:54 387 查看
我们先谈谈单继承的情况:

1.编译器能否识别多态,看是否有virtual关键字,如果有,那么在声明对象的时候,内存会分配一个vptr关键字和一个vptb表,其中vptr指向vptb表。

假定某一个虚函数f(),放在vptb的slot(2)中,一个虚函数g()凡在slot(3)中,当基类声明了一个虚函数,并且有子类继承基类的时候会出现二种情况:

1.基类的虚函数f()被子类重写,此时,子类有一个VPTR指针指向vptb表,在子类的vptb表的slot(2)中,也有一个f()函数,不过此时的f()函数类型是子类的。

2.基类的虚函数f()没有被子类重写,此时,子类有一个VPTR指针指向vptb表,在子类的vptb表的slot(2)中,也有一个f()函数,不过此时的f()函数类型是基类的。

那么有以上2点,在多态实现编译期就可以知道虚函数的偏移地址,唯一不知道的就是,是哪一个VPTR表的虚函数,那么这个问题会在执行期搞定。

例如 

ptr->f();

会被转化为

(*ptr->vptb[2])(ptr);

有vptr[2]我们已经知道了去执行哪一个函数,唯一不知道的就是,哪一个虚函数表的vptr[2].

在编译器的执行期,会告诉编译器去执行哪一个虚函数表,那么此时就完成了多态。

多继承的情况:

多继承的情况下,派生类内部的情况比较复杂,主要是:

1.产生了n个vptb表,其中n-1个是额外的vptb表;

2.第一个vptb是主要的表格,继承着第一个基类的vptb。

3.后面n-1个是次要的表格。

当基类base1的指针指向派生类的时候,那么和单继承的情况是一样的。

当基类base2的指针指向派生类的时候,那么会有指针地址的调整,像前调整(sizeof(base1))个单位。这些都是在执行期完成的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ 对象模型 多态