跟同学聊天的时候,说是一个类的对象只有一个虚表。可是多继承的是什么情况?比方说 c 继承 a 和 b 。 a , b 都有自己的虚表。那么 c 虚表到底是怎么维持的?书里说的是维持多个虚表,现在有变化么?
还有这样一个问题,以上图为例,就是说比方说我可以将一个Base1的指针(姑且叫做bp_1)指向派生类,但是很明显的,这个指针并不能调用另一个基类也就是Base2里的mumable函数。但是这个图里完全体现不出来这一点阿?
1
introom 2016-05-20 00:28:55 +08:00 via Android 1
一个类对应一个 vtbl, 如果有虚函数的话。
所以 c 这个实例有三个 vptr, 分别指向 vtbl{a,b,c} |
2
hxndg OP 倘若 c 又定义了一个虚函数,那么这个虚函数会扔到哪里呢?
|
4
sfqtsh 2016-05-20 02:03:31 +08:00 via Android 1
c 对象有两个虚函数表指针,指向两个虚函数表。 c 中覆盖的虚函数会替换掉两个表中同名的虚函数指针位置。若是普通多重继承,根据继承顺序, c 中多余的虚函数的地址会附加到第一个虚函数表指针指向的虚函数表的后面。
若是还有虚继承,根据不同的编译器实现,比如,微软家的,对象还会存在一个虚基表指针,指向一个虚基表,里面存有虚基类对象的偏移。 微软编译器有一个隐含的编译选项-d1reportSingleClassLayout 类名,可以很方便地查看对象内存分布,你可以以此学习。 |
5
hxndg OP @sfqtsh 这个多余的虚函数指的是什么?是指 c 里新定义,还是 c 通过继承 b 的来的 mumble ,也就是在图片里 Base1 subobject 的虚函数表里包含着 Base2 mumble 是这个多余的虚函数么?虚表的个数能否总结为上一层带有虚函数的类个数-1 呢?
|
7
lsmgeb89 2016-05-20 05:20:17 +08:00 1
实在弄不清楚,就写个代码看。
编译器有一些选项可以打印这些信息的,记得 VS 的 cl 和 g++ 都有。 |
8
visionsmile 2016-05-20 06:31:00 +08:00 via Android 1
有的编译器会把多个虚表合并成一个,有的是具有多个虚表。一个和多个都没什么妨碍,函数位置都能通过 offset 算出来的。
|
10
hxndg OP |
11
zuoxiaomo 2016-05-20 11:20:08 +08:00
c++ primer 里边有一章介绍虚函数表的
|
12
visionsmile 2016-05-20 11:40:50 +08:00 via Android 1
@hxndg 在多重继承下,一个 derived class 内含 n-1 个额外的 virtual tables , n 表示其上一层 base classes 的个数;针对每一个 virtual tables, derived 对象中有对应的 vptr.——深度探索 C++对象模型 P164
|
13
visionsmile 2016-05-20 11:43:24 +08:00 via Android 1
@hxndg Sun 编译器将多个 virtual tables 连锁为一个;指向次要表格的指针可由主要表格名称加上一个 offset 获得,这样的策略下每个 class 只有一个具名的 virtual table.—— P165
|
14
hxndg OP @visionsmile 首先很感激哈,我看到这里了。图 4.2 本身讲的也很清楚,但是具体编译器实现到底是怎么样的是我很好奇的,而且我很奇特的是为什么第一个虚表里面包含了第二个基类的虚函数。这些我没有搞明白所以提问的哈。坦白说我对于书中的一部分细节保持怀疑态度因为觉得还是不是很明白,可能我还是看的不认真把。
|