《挑战30天C++入门极限》图文例解C++类的多重继承与虚拟继承

时间:2022-06-25
本文章向大家介绍《挑战30天C++入门极限》图文例解C++类的多重继承与虚拟继承,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。






 

图文例解C++类的多重继承与虚拟继承

  在过去的学习中,我们始终接触的单个类的继承,但是在现实生活中,一些新事物往往会拥有两个或者两个以上事物的属性,为了解决这个问题,C++引入了多重继承的概念,C++允许为一个派生类指定多个基类,这样的继承结构被称做多重继承。

举个例子,交通工具类可以派生出汽车和船连个子类,但拥有汽车和船共同特性水陆两用汽车就必须继承来自汽车类与船类的共同属性。 

  由此我们不难想出如下的图例与代码:

  //站点:www.cndev-lab.com //所有稿件均有版权,如要转载,请务必著名出处和作者 #include <iostream> using namespace std; class Vehicle { public: Vehicle(int weight = 0) { Vehicle::weight = weight; } void SetWeight(int weight) { cout<<"重新设置重量"<<endl; Vehicle::weight = weight; } virtual void ShowMe() = 0; protected: int weight; }; class Car:public Vehicle//汽车 { public: Car(int weight=0,int aird=0):Vehicle(weight) { Car::aird = aird; } void ShowMe() { cout<<"我是汽车!"<<endl; } protected: int aird; }; class Boat:public Vehicle//船 { public: Boat(int weight=0,float tonnage=0):Vehicle(weight) { Boat::tonnage = tonnage; } void ShowMe() { cout<<"我是船!"<<endl; } protected: float tonnage; }; class AmphibianCar:public Car,public Boat//水陆两用汽车,多重继承的体现 { public: AmphibianCar(int weight,int aird,float tonnage) :Vehicle(weight),Car(weight,aird),Boat(weight,tonnage) //多重继承要注意调用基类构造函数 { } void ShowMe() { cout<<"我是水陆两用汽车!"<<endl; } }; int main() { AmphibianCar a(4,200,1.35f);//错误 a.SetWeight(3);//错误 system("pause"); }   上面的代码从表面看,看不出有明显的语发错误,但是它是不能够通过编译的。这有是为什么呢?   这是由于多重继承带来的继承的模糊性带来的问题。   先看如下的图示:

  在图中深红色标记出来的地方正是主要问题所在,水陆两用汽车类继承了来自Car类与Boat类的属性与方法,Car类与Boat类同为AmphibianCar类的基类,在内存分配上AmphibianCar获得了来自两个类的SetWeight()成员函数,当我们调用a.SetWeight(3)的时候计算机不知道如何选择分别属于两个基类的被重复拥有了的类成员函数SetWeight()。   由于这种模糊问题的存在同样也导致了AmphibianCar a(4,200,1.35f);执行失败,系统会产生Vehicle”不是基或成员的错误。   以上面的代码为例,我们要想让AmphibianCar类既获得一个Vehicle的拷贝,而且又同时共享用Car类与Boat类的数据成员与成员函数就必须通过C++所提供的虚拟继承技术来实现。   我们在Car类和Boat类继承Vehicle类出,在前面加上virtual关键字就可以实现虚拟继承,使用虚拟继承后,//站点:www.cndev-lab.com //所有稿件均有版权,如要转载,请务必著名出处和作者 #include <iostream> using namespace std; class Vehicle { public: Vehicle(int weight = 0) { Vehicle::weight = weight; cout<<"载入Vehicle类构造函数"<<endl; } void SetWeight(int weight) { cout<<"重新设置重量"<<endl; Vehicle::weight = weight; } virtual void ShowMe() = 0; protected: int weight; }; class Car:virtual public Vehicle//汽车,这里是虚拟继承 { public: Car(int weight=0,int aird=0):Vehicle(weight) { Car::aird = aird; cout<<"载入Car类构造函数"<<endl; } void ShowMe() { cout<<"我是汽车!"<<endl; } protected: int aird; }; class Boat:virtual public Vehicle//船,这里是虚拟继承 { public: Boat(int weight=0,float tonnage=0):Vehicle(weight) { Boat::tonnage = tonnage; cout<<"载入Boat类构造函数"<<endl; } void ShowMe() { cout<<"我是船!"<<endl; } protected: float tonnage; }; class AmphibianCar:public Car,public Boat//水陆两用汽车,多重继承的体现 { public: AmphibianCar(int weight,int aird,float tonnage) :Vehicle(weight),Car(weight,aird),Boat(weight,tonnage) //多重继承要注意调用基类构造函数 { cout<<"载入AmphibianCar类构造函数"<<endl; } void ShowMe() { cout<<"我是水陆两用汽车!"<<endl; } void ShowMembers() { cout<<"重量:"<<weight<<"顿,"<<"空气排量:"<<aird<<"CC,"<<"排水量:"<<tonnage<<"顿"<<endl; } }; int main() { AmphibianCar a(4,200,1.35f); a.ShowMe(); a.ShowMembers(); a.SetWeight(3); a.ShowMembers(); system("pause"); }   注意观察类构造函数的构造顺序。   虽然说虚拟继承与虚函数有一定相似的地方,但读者务必要记住,他们之间是绝对没有任何联系的!