出现原因
在多重继承时 尤其是钻石继承时容易出现问题,若 B C 皆继承自 A 类,A 类中有变量 a
class A
{
int a;
};
而 B 中有获取 a 的方法 Get, C 中有设置 a 的方法 Set,
class B : public A
{
public:
int Get() {
return a; }
};
class C : public A
{
void Set(int val) {
a = val };
};
此时若出现 D 类,继承 B 和 C
class D : public B, public C
{
};
那么使用 D Get 和 Set 的 a 为同一个吗?
答案是否定的,B,C 继承 A,则 B,C 中均有一个 a, B 中的 Get 只能操作 B 中的 a, C 中的 Set 只能操作 C 中的 a ,这就是问题所在了
解决方法
在 B C 继承 A 时,使用虚继承,继承时使用 virtual 关键字,即:
class B : public virtual A
{
public:
int Get() {
return a; }
};
class C : public virtual A
{
void Set(int val) {
a = val };
};
此时 D 再正常继承 B,C 则不会出现问题,
虚继承表示构建时,构建 B 和 C 时,不构建 B 和 C 类对象中的 A ,在构建 D 类对象时 构建一次 A ,则在 D 中只存在一个 a 变量
代码示例
#include <iostream>
using namespace std;
class A {
public:
A(const char* s) {
cout << s << endl; }
};
class B : public virtual A {
public:
B(const char* s1, const char* s2) :A(s1) {
cout << s2 << endl; }
};
class C : public virtual A {
public:
C(const char* s1, const char* s2) :A(s1) {
cout << s2 << endl; }
};
class D : public B, C {
public:
D(const char* s1, const char* s2, const char* s3, const char* s4) :B(s1, s2), C(s3, s4), A(s1)
{
cout << s4 << endl;
}
};
int main() {
D d("class A", "class B", "class C", "class D");
}
由于B,C 为虚继承不会构造 A ,则打印为
class A
class B
class D
class D