11. 虚继承
在继承的过程中有时会出现用一个类派生出多个子类,又通过多继承将多个子类派生出一个子类。这种创建的子类对象中可能会包含多个基类对象。
以下是多继承中的一个著名案例,菱形继承(也叫钻石继承)。
A
/ \
B C
\ /
D
B 类继承自 A类,因此 B 类对象即包含自身的成员,也会包含 A 类的成员。同理 C 类对象也会包含 A 类的成员。又因为 D 类继承自 B 类和 C 类,因此 D 类的对象就有两份 A 类的成员变量(一份来自于 B 类,一份来自于 C 类)。而 D 类根本就不需要两份 A 类成员(会出现冲突)。解决这个问题的语法是使用虚继承。
虚继承的语法
class 子类名: virtual 继承方式 父类名 {
};
示例
// filename: diamond.cpp
#include <iostream>
using namespace std;
class A {
public:
A() : a(1) {}
void method() {
cout << "a:" << a << endl;
}
private:
int a;
};
class B : virtual public A {
public:
B() : A(), b(2) {}
private:
int b;
};
class C : virtual public A {
public:
C() : A(), c(3) {}
private:
int c;
};
class D : public B, public C {
public:
D() : B(), C(), d(4) {}
private:
int d;
};
int main(int argc, char * argv[]) {
D d;
d.method();
return 0;
}
编译和运行结果如下:
weimz@mzstudio:~$ g++ -o diamond diamond.cpp
weimz@mzstudio:~$ ./diamond
a:1
上述代码中, B 类和 C 类都是虚继承自 A 类,因此在多继承创建 D 类时D 类中只有一个 A 类的对象,否则编译则会出现成员函数或者成员变量出现争议(ambiguous) 的编译错误。