C ++:是具有虚拟基础但没有虚拟函数多态且具有VTable的类吗? [英] C++: is a class with virtual base but without virtual functions polymorphic and has VTable?

查看:110
本文介绍了C ++:是具有虚拟基础但没有虚拟函数多态且具有VTable的类吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下代码:

#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;
}

在我的系统上它会打印

4
8
12
0
0
0

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

Which means that none of these classes is polymorphic. However, sizes of B1 and B2 differ by exactly size of a pointer, which is probably a pointer to vtable. I've ran gcc with -fdump-class-hierarchy and got:

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

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

Here is a question: what is a polymorphic class? Does 'having vtable' means 'be polymorphic and have RTTI' and vice-versa? If not, why do it have to have at least one virtual function to be polymorphic, if it's going to have vtable anyway?

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

Looks like definition of polymorphic class differs from 'the class that has a vtable', because, as we can see above, B2 is not a polymorphic, but has a vtable and, as I think, should have a RTTI. In this document it's clearly stated that "polymorphic - i.e. have at least one virtual function. (This is necessary to allow the generated dispatch code to use RTTI on the classes.)".

推荐答案

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

You are missing a detail here: virtual tables are an implementation detail. As a result:

  • 该标准将 polymorphic 类定义为可以在多态意义上使用的类:即,可以覆盖行为的地方
  • 编译器使用虚拟表来实现标准规定的某些功能/行为,这些功能/行为恰好同时包含多态类和虚拟基数.
  • the Standard defines polymorphic classes as classes that can be used in a polymorphic sense: ie, where behavior can be overriden
  • compilers use virtual tables to implement some features/behaviors mandated by the Standard, which happen to include both polymorphic classes AND virtual bases.

因此,我所知道的编译器(MSVC以及遵循Itanium ABI的那些编译器,例如gcc,icc和Clang)将使用虚拟表来提供dynamic_cast在其中运行所需的RTTI.虚拟基础的存在...而且这与类是否是多态的没有任何关系.

Thus, yes the compilers I know (MSVC and those following the Itanium ABI such as gcc, icc and Clang) will use virtual tables to provide the RTTI necessary for dynamic_cast to work in the presence of virtual bases... and no this has nothing to do really with whether a class is polymorphic or not.

在切线上,优先考虑继承而不是继承意味着,如果没有可替代的行为,则没有理由从类继承.

On a tangent, though, Prefer Composition Over Inheritance implies that there is little reason to inherit from a class if there is no behavior that can be overriden.

这篇关于C ++:是具有虚拟基础但没有虚拟函数多态且具有VTable的类吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆