面试题答案
一键面试代码示例
#include <iostream>
// 定义基类A
class A {
public:
int a;
A(int value) : a(value) {
std::cout << "A constructor" << std::endl;
}
};
// 定义基类B,继承自A
class B : virtual public A {
public:
B(int value) : A(value) {
std::cout << "B constructor" << std::endl;
}
};
// 定义基类C,继承自A
class C : virtual public A {
public:
C(int value) : A(value) {
std::cout << "C constructor" << std::endl;
}
};
// 定义派生类D,多重继承自B和C
class D : public B, public C {
public:
D(int value) : A(value), B(value), C(value) {
std::cout << "D constructor" << std::endl;
}
};
int main() {
D d(10);
return 0;
}
原理解释
- 多重继承:在C++中,一个类可以从多个基类继承成员。例如,
D
类从B
类和C
类继承。在D
类的构造函数初始化列表中,需要按照继承列表的顺序(B
在前,C
在后)初始化B
和C
。 - 菱形继承:当存在菱形继承结构(如
A
被B
和C
继承,D
又继承自B
和C
)时,为了避免A
的成员在D
中出现两份,B
和C
需要使用virtual
关键字来继承A
,这种继承方式称为虚继承。 - 初始化列表:在
D
类的构造函数初始化列表中,首先初始化虚基类A
,这是因为虚基类的初始化责任由最底层的派生类(这里是D
)承担。然后按照继承顺序初始化B
和C
。如果不先初始化虚基类A
,可能会导致未定义行为。
通过这种方式,可以确保在复杂的继承体系中,基类成员被正确初始化,并且避免菱形继承带来的歧义问题。