到底 C++多继承里几个虚表?

2016-05-20 00:14:00 +08:00
 hxndg

跟同学聊天的时候,说是一个类的对象只有一个虚表。可是多继承的是什么情况?比方说 c 继承 a 和 b 。 a , b 都有自己的虚表。那么 c 虚表到底是怎么维持的?书里说的是维持多个虚表,现在有变化么?

5510 次点击
所在节点    问与答
14 条回复
introom
2016-05-20 00:28:55 +08:00
一个类对应一个 vtbl, 如果有虚函数的话。
所以 c 这个实例有三个 vptr, 分别指向 vtbl{a,b,c}
hxndg
2016-05-20 00:29:26 +08:00
倘若 c 又定义了一个虚函数,那么这个虚函数会扔到哪里呢?
hxndg
2016-05-20 00:30:12 +08:00
@introom 也就是说如果 c 又定义了一个虚函数,那么又多一个虚表了?
sfqtsh
2016-05-20 02:03:31 +08:00
c 对象有两个虚函数表指针,指向两个虚函数表。 c 中覆盖的虚函数会替换掉两个表中同名的虚函数指针位置。若是普通多重继承,根据继承顺序, c 中多余的虚函数的地址会附加到第一个虚函数表指针指向的虚函数表的后面。
若是还有虚继承,根据不同的编译器实现,比如,微软家的,对象还会存在一个虚基表指针,指向一个虚基表,里面存有虚基类对象的偏移。

微软编译器有一个隐含的编译选项-d1reportSingleClassLayout 类名,可以很方便地查看对象内存分布,你可以以此学习。
hxndg
2016-05-20 02:33:46 +08:00
@sfqtsh 这个多余的虚函数指的是什么?是指 c 里新定义,还是 c 通过继承 b 的来的 mumble ,也就是在图片里 Base1 subobject 的虚函数表里包含着 Base2 mumble 是这个多余的虚函数么?虚表的个数能否总结为上一层带有虚函数的类个数-1 呢?
sfqtsh
2016-05-20 02:53:27 +08:00
@hxndg
1.指新定义的
2.不能。
lsmgeb89
2016-05-20 05:20:17 +08:00
实在弄不清楚,就写个代码看。

编译器有一些选项可以打印这些信息的,记得 VS 的 cl 和 g++ 都有。
visionsmile
2016-05-20 06:31:00 +08:00
有的编译器会把多个虚表合并成一个,有的是具有多个虚表。一个和多个都没什么妨碍,函数位置都能通过 offset 算出来的。
hxndg
2016-05-20 10:12:34 +08:00
@lsmgeb89 我能问问 g++是什么选项不?我搜了,没找到~………
hxndg
2016-05-20 10:52:12 +08:00
@visionsmile
@lsmgeb89
@sfqtsh
@introom
去 google 上搜了一下,然后搜到了,尴尬。。。。表示这个有点炯,感谢诸位。
zuoxiaomo
2016-05-20 11:20:08 +08:00
c++ primer 里边有一章介绍虚函数表的
visionsmile
2016-05-20 11:40:50 +08:00
@hxndg 在多重继承下,一个 derived class 内含 n-1 个额外的 virtual tables , n 表示其上一层 base classes 的个数;针对每一个 virtual tables, derived 对象中有对应的 vptr.——深度探索 C++对象模型 P164
visionsmile
2016-05-20 11:43:24 +08:00
@hxndg Sun 编译器将多个 virtual tables 连锁为一个;指向次要表格的指针可由主要表格名称加上一个 offset 获得,这样的策略下每个 class 只有一个具名的 virtual table.—— P165
hxndg
2016-05-20 15:52:32 +08:00
@visionsmile 首先很感激哈,我看到这里了。图 4.2 本身讲的也很清楚,但是具体编译器实现到底是怎么样的是我很好奇的,而且我很奇特的是为什么第一个虚表里面包含了第二个基类的虚函数。这些我没有搞明白所以提问的哈。坦白说我对于书中的一部分细节保持怀疑态度因为觉得还是不是很明白,可能我还是看的不认真把。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/279895

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX