面试题答案
一键面试- 类D对象的内存布局:
- 首先是B类的部分,包含B类自己的数据成员(如果有),以及指向虚基类A子对象的虚基表指针(如果有虚继承相关的数据结构)。
- 接着是C类的部分,包含C类自己的数据成员(如果有),以及指向虚基类A子对象的虚基表指针(因为C也虚继承自A)。
- 最后是D类自己的数据成员(如果有)。虚基类A的子对象在内存中只会有一份,通常在D对象内存布局的最后部分(不同编译器实现可能略有差异)。
- 虚继承对内存布局的影响:
- 引入虚基表指针,用于指向虚基类子对象,确保虚基类子对象在最终派生类对象中只有一份实例,避免了菱形继承带来的多重实例问题。这使得内存布局更为复杂,因为需要额外的指针来维护虚基类子对象的位置。
- 代码示例:
#include <iostream>
class A {
public:
int a;
};
class B : virtual public A {
public:
int b;
};
class C : virtual public A {
public:
int c;
};
class D : public B, public C {
public:
int d;
};
int main() {
D d;
d.a = 1;
d.b = 2;
d.c = 3;
d.d = 4;
std::cout << "a: " << d.a << ", b: " << d.b << ", c: " << d.c << ", d: " << d.d << std::endl;
return 0;
}
在上述代码中,B
和C
虚继承自A
,D
继承自B
和C
。通过虚继承,D
对象中A
的子对象只有一份,避免了菱形继承中A
子对象的重复。