tangjikede 2020-04-30
C++支持多继承,由此引发错综复杂的命名冲突问题,这时需要虚继承的概念解决这些问题。在C++之后的Java不支持多继承,因此没有这些问题。
多继承是指从多个直接基类中产生派生类的方法,多继承的派生类继承了所有父类成员。多个基类相互交织产生了错综复杂的设计问题,命名冲突就是其中一个。以典型的菱形继承为例,
B和C由A派生而来,D又由B和C多继承而来,此时D中的成员变量由A->B->D, A->C->D两条路继承而来,如果A中有一个成员变量a,D直接使用a就会就会产生歧义,编译器不知道这个a来自直接基类B还是C。编译器会报错。
C++为了解决多继承产生的命名冲突和数据冗余,提出了虚继承的方法,使派生类中只保留一份间接基类的成员(上图中A是间接基类,B,C是直接基类)。在继承方式前加virtual关键字就是虚继承。
虚继承是让某个类做出声明承诺共享它的基类。被共享的这个基类就叫做“虚基类”。不论虚基类在继承体系中出现多少次,派生类中都只有一份虚基类的成员变量。
C++不取消多继承有一个重要的原因就是,它的标准库中最常使用的iostream类就是一个典型的多继承。iostream从istream和ostream直接继承而来,而istream和ostream都继承自一个名叫base_ios的类。这是典型的菱形继承。这里的istream和ostream都必须声明为虚继承。但是我们在实践中不提倡多继承,它会增加程序的模式复杂度,难以进行维护。可以单一继承的就应当单一继承。