C++:是一个具有虚拟基础的类但没有虚函数的多态并且具有VTable?

yep*_*ons 6 c++ polymorphism virtual-functions rtti virtual-inheritance

请考虑以下代码:

#include <iostream>
#include <typeinfo>
#include <type_traits>

using namespace std;

struct A { int data; };
struct B1 : A {};
struct B2 : virtual A {};

struct Base1 : virtual A {};
struct Base2 : virtual A {};
struct Derived : Base1, Base2 {};

int main() {
  cout << sizeof(B1) << endl;
  cout << sizeof(B2) << endl;
  cout << sizeof(Derived) << endl;

  cout << std::is_polymorphic<B1>::value << endl;
  cout << std::is_polymorphic<B2>::value << endl;
  cout << std::is_polymorphic<Derived>::value << endl;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

在我的系统上打印

4
8
12
0
0
0
Run Code Online (Sandbox Code Playgroud)

这意味着这些类都不是多态的.但是,B1和B2的大小完全不同于指针的大小,这可能是指向vtable的指针.我已经运行了gcc -fdump-class-hierarchy并得到了:

Vtable for B2
B2::_ZTV2B2: 3u entries
0     4u
4     (int (*)(...))0
8     (int (*)(...))(& _ZTI2B2)

VTT for B2
B2::_ZTT2B2: 1u entries
0     ((& B2::_ZTV2B2) + 12u)

Class B2
   size=8 align=4
   base size=4 base align=4
B2 (0x0x3ca5400) 0 nearly-empty
    vptridx=0u vptr=((& B2::_ZTV2B2) + 12u)
  A (0x0x3c972d8) 4 virtual
      vbaseoffset=-12
Run Code Online (Sandbox Code Playgroud)

这是一个问题:什么是多态类?'vtable'是否意味着'具有多态性并具有RTTI',反之亦然?如果没有,为什么它必须至少有一个虚拟函数是多态的,如果它仍然有vtable?

看起来多态类的定义不同于'具有vtable的类',因为,正如我们上面所看到的,B2不是多态的,而是有一个vtable,并且我认为应该有一个RTTI.在文档中,明确指出"多态 - 即至少有一个虚函数.(这是允许生成的调度代码在类上使用RTTI所必需的.)".

Mat*_* M. 6

您在这里缺少一个细节:虚拟表是一个实现细节.结果是:

  • 标准将多态类定义为可以在多态意义上使用的类:即,可以覆盖行为的位置
  • 编译器使用虚拟表来实现标准规定的某些功能/行为,这些功能/行为恰好包括多态类和虚拟基础.

因此,编译器,我知道(MSVC和那些以下安腾ABI如gcc,国际刑事法院与锵)将使用虚拟表提供RTTI必要dynamic_cast在虚拟基地的存在......工作,没有这个有没有关系确实一个类是否是多态的.

但是,在切线上,Prefer Composition Over Inheritance意味着如果没有可以覆盖的行为,则没有理由从类继承.