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所必需的.)".
您在这里缺少一个细节:虚拟表是一个实现细节.结果是:
因此,对编译器,我知道(MSVC和那些以下安腾ABI如gcc,国际刑事法院与锵)将使用虚拟表提供RTTI必要dynamic_cast在虚拟基地的存在......工作,没有这个有没有关系确实一个类是否是多态的.
但是,在切线上,Prefer Composition Over Inheritance意味着如果没有可以覆盖的行为,则没有理由从类继承.