nab*_*bil 3 c++ struct structure virtual-inheritance
struct A {
int i;
virtual void f() { cout << i; }
A() { i = 1; }
A(int _i) : i(_i) {}
};
struct B : A {
B() : A(2) { f(); }
void f() { cout << i+10; }
};
struct C : B, virtual A {
C() : A() {}
};
Run Code Online (Sandbox Code Playgroud)
你能否解释为什么在C结构中会有两个A :: i以及为什么会有两个vptr指针指向C结构的'虚表表方法',尽管A只有虚方法?我知道当从一个公共基地有虚拟继承时,会有一个共同基础的实例而不是两个,请指教!
Mis*_*sch 13
没有虚拟
当没有继承时virtual,你可以想象内存结构是这样的:
class B : A {};
Run Code Online (Sandbox Code Playgroud)

变量A是"内部"(正上方)类的变量B.
使用虚拟
继承时virtual,B只需要一个"指针" A:
class B : virtual A {};
Run Code Online (Sandbox Code Playgroud)

您的示例
这意味着,您的示例如下所示:
class B : A
class C : B, virtual A
Run Code Online (Sandbox Code Playgroud)

只有一个实例A
如果你只想要一个实例A,你必须使用virtual两次:
class B : virtual A
class C : B, virtual A
Run Code Online (Sandbox Code Playgroud)

下面是代码的布局,因为它是由g ++(生成的-fdump-class-hierarchy)生成的:
Class C
size=16 align=4
base size=8 base align=4
C (0xb7193440) 0
vptridx=0u vptr=((& C::_ZTV1C) + 12u)
B (0xb719f078) 0
primary-for C (0xb7193440)
A (0xb719a428) 0
primary-for B (0xb719f078)
A (0xb719a460) 8 virtual
vptridx=4u vbaseoffset=-12 vptr=((& C::_ZTV1C) + 28u)
Run Code Online (Sandbox Code Playgroud)
关于vpointers和vtables,我有点生疏,所以我不确定为什么会有那些v-pointers.
但是,我可以告诉你,你假设只有一种虚方法是错误的.因为B继承自A并且A::f()是虚拟的,所以派生B::f()自动也是虚拟的,即使您没有明确地将其写下来.
编辑:
挖了一下之后,我想我还记得哪些是需要的指针,哪些不是.但是,我不会对您提供以下任何保证.
在下文中,符号C.B.A表示A-subobject Bin C,用于区分两个子A对象(C.B.A和C.A).
每个子类都需要一个v-pointer.然而*(C.B.A),*(C.B)并*C都指向同一个位置(类即开始C,这也是年初C.B和C.B.A,因此它们可以共享一个vpointer.但是一个指向子类*(C.A)将指向不同的位置,因此另一个vpointer是需要注意的是,C.B.A在你的例子中甚至无法访问子类(gcc:"警告:直接基础''由于歧义而在'C'中无法访问'".
为了使它更清楚:
如果你只有以下结构
class B : A {};
class C : B {};
Run Code Online (Sandbox Code Playgroud)
因为所有指向任何子类的指针C都指向同一位置,所以只需要一个vpointer .vpointer只需要指向任一个的vtable A,B或者C告诉哪个是对象的运行时类型.
| 归档时间: |
|
| 查看次数: |
7032 次 |
| 最近记录: |