【发布时间】:2012-07-21 03:18:38
【问题描述】:
考虑以下层次结构:
struct A {
int a;
A() { f(0); }
A(int i) { f(i); }
virtual void f(int i) { cout << i; }
};
struct B1 : virtual A {
int b1;
B1(int i) : A(i) { f(i); }
virtual void f(int i) { cout << i+10; }
};
struct B2 : virtual A {
int b2;
B2(int i) : A(i) { f(i); }
virtual void f(int i) { cout << i+20; }
};
struct C : B1, virtual B2 {
int c;
C() : B1(6),B2(3),A(1){}
virtual void f(int i) { cout << i+30; }
};
-
C实例的确切内存布局是什么?它包含多少个 vptr,每个 vptr 的确切放置位置?哪些虚拟表与 C 的虚拟表共享?每个虚拟表究竟包含什么?我是如何理解布局的:
---------------------------------------------------------------- |vptr1 | AptrOfB1 | b1 | B2ptr | c | vptr2 | AptrOfB2 | b2 | a | ----------------------------------------------------------------其中
AptrOfBx是指向Bx包含的A实例的指针(因为继承是虚拟的)。
那是对的吗?vptr1指向哪些函数?vptr2指向哪些函数? -
给定以下代码
C* c = new C(); dynamic_cast<B1*>(c)->f(3); static_cast<B2*>(c)->f(3); reinterpret_cast<B2*>(c)->f(3);为什么所有对
f的调用都打印33?
【问题讨论】:
-
这是作业,还是好奇?
-
其实这是考试。但我敢肯定,如果我最终理解了这个例子中的事情是如何工作的,我就能理解与多重继承和虚拟继承相关的任何事情。
-
您可以像这样轻松找出每个父子对象的起点:
C foo; intptr_t offsetB1 = (intptr_t)(B1*)&foo - (intptr_t)&foo;,其他基础的起点可以类似推导出。此外,计算所有类的sizeof应该会给你另一个很好的线索。
标签: c++ multiple-inheritance vtable virtual-inheritance memory-layout