【发布时间】:2012-08-15 00:21:22
【问题描述】:
来自Large-Scale C++ Software Design (Lakos),第 652 页:
问题是,“编译器会将给定类的虚拟表定义存放在哪个唯一的翻译单元中?”。 CFRONT(和许多其他 C++ 实现)采用的技巧是将外部虚拟表放置在翻译单元中,该翻译单元定义了出现在类中的第一个词法上的非内联函数(如果存在的话)。
最常用的编译器(GCC 和 Visual C++)是否仍然如此?还是曾经?
【问题讨论】:
-
这纯粹是实现定义的。编译器甚至可能没有虚拟表或虚拟指针,并以自己喜欢的方式实现动态调度。
-
@Als:哦,是的,编译器可以做的事情是无限多的。然而,这个问题很实际,这是列出的编译器实际所做的。
-
@Als "编译器甚至可能没有虚拟表或虚拟指针,并以自己喜欢的方式实现动态调度。" 尽管如此,实际上,每个现实世界的编译器都使用vtables,vptr...
-
+1 这是一个有效的问题。不是最关键或最引人入胜的 C++,而是关于现实世界实现的一个有效问题。
-
现代链接器通常具有合并相同符号定义的多个副本的能力,因此是否为同一类生成多个虚拟表副本不再那么重要;链接时它们很可能会合并。但是,如果析构函数是虚拟的(因此必须生成一个外行版本),将虚拟表放在析构函数所在的位置是最有意义的。当然,在析构函数的外联版本中,也如果析构函数被声明为内联,则可能在多个翻译单元中存在副本。
标签: c++ visual-c++ gcc compilation vtable