上面图称为菱形继承也叫做钻石继承,类B、C分别继承于A, D由同时继承于B和C.(C++和Python有多重继承机制,java没有)
用伪代码实现如下:
class Animal { /* ... */ }; // 基类
{
int weight;
public:
int getWeight() { return weight;};
};
class Tiger : public Animal { /* ... */ };
class Lion : public Animal { /* ... */ }
class Liger : public Tiger, public Lion { /* ... */ };
一、菱形继承会出现什么问题?
int main( )
{
Liger lg ;
/*编译错误,下面的代码不会被任何C++编译器通过 */
int weight = lg.getWeight();
}
在我们的继承结构中,我们可以看出Tiger和Lion类都继承自Animal基类。所以问题是:因为Liger多重继承了Tiger和Lion类,因此Liger类会有两份Animal类的成员(数据和方法),Liger对象”lg”会包含Animal基类的两个子对象。
所以,会出现什么问题?再看看上面的代码-调用”lg.getWeight()”将会导致一个编译错误。这是因为编译器并不知道是调用Tiger类的getWeight()还是调用Lion类的getWeight()。所以,调用getWeight方法是不明确的,因此不能通过编译。
二、解决方法
如果Lion类和Tiger类在分别继承Animal类时都用virtual来标注,对于每一个Liger对象,C++会保证只有一个Animal类的子对象会被创建。看看下面的代码:
class Tiger : virtual public Animal { /* ... */ };
class Lion : virtual public Animal { /* ... */ }
你可以看出唯一的变化就是我们在类Tiger和类Lion的声明中增加了”virtual”关键字。现在类Liger对象将会只有一个Animal子对象,下面的代码编译正常:
int main( )
{
Liger lg ;
/*既然我们已经在Tiger和Lion类的定义中声明了"virtual"关键字,
于是下面的代码编译OK */
int weight = lg.getWeight();
}
虚继承是一种机制,类通过虚继承指出它希望共享虚基类的状态。对给定的虚基类,无论该类在派生层次中作为虚基类出现多少次,只继承一个共享的基类子对象,共享基类子对象称为虚基类。虚基类用virtual声明继承关系就行了