您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 咨询培训 > 03-C++课件-继承(4)-多继承
继承与派生继承与派生1继承概述2基类和派生类3派生类的构造与析构4多继承多继承举例兼职技术人员管理人员销售人员销售经理雇员多继承一个类有多个直接基类的继承关系称为多继承多继承声明语法class派生类名:访问控制基类名1,…,访问控制基类名n{数据成员和成员函数声明};多继承classC:publicA,publicBclassAclassB类C可以根据访问控制同时继承类A和类B的成员,并添加自己的成员多继承的简单应用classBase1{public:Base1(intx){value=x;}intgetData()const{returnvalue;}protected:intvalue;};classBase2{public:Base2(charc){letter=c;}chargetData()const{returnletter;}protected:charletter;};7.5.1多继承的派生类构造和访问多继承的简单应用classDerived:publicBase1,publicBase2{public:Derived(int,char,double);doublegetReal()const;private:doublereal;};voidmain(){Base1b1(10);Base2b2('k');Derivedd(5,'A',2.5);}'K'2.5'A'510valueletterrealBasc1b1Basc2b2Derivedd多个基类的派生类构造函数用初始化列表调用基类构造函数,执行顺序与单继承构造函数情况类似。多个直接基类构造函数执行顺序取决于定义派生类时指定的各个继承基类的顺序。按基类在被继承时所声明的次序从左到右依次调用。多继承的派生类构造一个派生类对象拥有多个直接或间接基类的成员。不同名成员访问不会出现二义性。如果不同的基类有同名成员,派生类对象访问时应该加以识别。多继承的派生类访问由于多继承情况下,可能造成对基类中某个成员的访问出现了不惟一的情况,则称为对基类成员访问的二义性问题。多重继承图示Af()CA::f();B::f();B::g();g();h();Bf();g();二义性和支配原则classC:publicA,publicB{public:voidg();voidh();};若有Cobj;则对函数f()的访问是二义的:obj.f();classA{public:voidf();};classB{public:voidf();voidg();};二义性和支配原则1.同名成员的二义性不同基类中有同名函数,使用基类名可避免这种二义:基类与派生类同名函数这种用基类名来控制成员访问的规则称为支配原则。voidC::f(){A::f();//B::f();}obj.A::f();obj.B::f();obj.g();//隐含用C的g()obj.B::g();//用B的g()二义性和支配原则2.同一基类被多次继承产生的二义性一个类不能从同一类直接继承二次或更多次。classC:publicB1,publicB2classB1classB2classBclassB{public:intb;};classB1:publicB{intb1;};classB2:publicB{intb2;};classC:publicB1,publicB2{public:intf();private:intd;};有:Cobj;obj.b;//errorojb.B::b;//error,从哪里继承的?classC{f(),d}classB1{b1}classB2{b2}classB{bb}classB{bb}obj.B1::bobj.B2::b二义性和支配原则例如:classB{public:intb;};classB1:publicB{intb1;};classB2:publicB{intb2;};classC:publicB1,publicB2{public:intf();private:intd;};classC{f(),d}classB1{b1}classB2{b2}classB{b}classB{b}c.bc.b1c.bc.b2c.dBBB1B2C多重派生类C的对象的存储结构示意建立C类的对象时,B的构造函数将被调用两次:分别由B1调和B2调用,以初始化C类的对象中所包含的两个B类的子对象二义性和支配原则虚基类如果在多条继承路经上有一个公共的基类,那么在继承路经的某处汇合点,这个公共基类就会在派生类的对象中产生多个基类子对象要使这个公共基类在派生类中只产生一个子对象,必须将这个基类声明为虚基类。虚基类声明使用关键字virtual例如:classB{public:intb;};classB1:virtualpublicB{intb1;};classB2:virtualpublicB{intb2;};classC:publicB1,publicB2{private:floatd;};有:cc.b//CccclassC{d}classB1{b1}classB2{b2}classB{b}由于类C的对象中只有一个B类子对象,名字b被约束到该子对象上,所以,当以不同路径使用名字b访问B类的子对象时,所访问的都是那个唯一的基类子对象。即cc.B1::b和cc.B2::b引用是同一个基类B的子对象二义性和支配原则例如:classB{public:intb;};classB1:virtualpublicB{private:intb1;};classB2:virtualpublicB{private:intb2;};classC:publicB1,publicB2{private:floatd;};classC{d}classB1{b1}classB2{b2}classB{b}带有虚基类的派生类C的对象的存储结构示意c.b1c.b2c.dc.bBB1B2C二义性和支配原则#includeiostream.hclassA{public:A(){coutclassAendl;}};classB:publicA{public:B(){coutclassBendl;}};classC:publicA{public:C(){coutclassCendl;}};classD:publicB,publicC{public:D(){coutclassDendl;}};voidmain(){Ddd;}例8虚继承的测试classDclassBclassCclassAclassA两次调用A的构造函数7.5.2虚基类#includeiostream.hclassA{public:A(){coutclassAendl;}};classB:publicA{public:B(){coutclassBendl;}};classC:publicA{public:C(){coutclassCendl;}};classD:publicB,publicC{public:D(){coutclassDendl;}};voidmain(){Ddd;}classDclassBclassCclassAclassA:virtualpublicAclassDclassBclassCclassA一次调用A的构造函数7.5.2虚基类例8虚继承的测试:virtualpublicA虚基类的构造函数由于派生类的对象中只有一个虚基类对象。为保证虚基类对象只被初始化一次,这个虚基类构造函数必须只被调用一次。规定将在建立对象时所指定的类称为最直接派生类。虚基类对象是由最直接派生类的构造函数通过调用虚基类的构造函数进行初始化的。从虚基类直接或间接继承的派生类中的构造函数的成员初始化列表中都要列出这个虚基类构造函数的调用。但是,只有用于建立对象的那个派生类的构造函数调用虚基类的构造函数,而该派生类的基类中所列出的对这个虚基类的构造函数调用在执行中被忽略。
本文标题:03-C++课件-继承(4)-多继承
链接地址:https://www.777doc.com/doc-4713497 .html