精华内容
下载资源
问答
  • 多重继承
    千次阅读
    2022-02-21 19:52:42

    多重继承的语法

    多重继承的语法也很简单,将多个基类用逗号隔开即可。例如已声明了类A、类B和类C,那么可以这样来声明派生类D:

    class D: public A, private B, protected C{
        //类D新增加的成员
    }
    

    D 是多继承形式的派生类,它以公有的方式继承 A 类,以私有的方式继承 B 类,以保护的方式继承 C 类。D 根据不同的继承方式获取 A、B、C 中的成员,确定它们在派生类中的访问权限。

    多重继承下的构造函数

    多继承形式下的构造函数和单继承形式基本相同,只是要在派生类的构造函数中调用多个基类的构造函数。以上面的 A、B、C、D 类为例,D 类构造函数的写法为:

    D(形参列表): A(实参列表), B(实参列表), C(实参列表){
        //其他操作
    }
    

    基类构造函数的调用顺序和和它们在派生类构造函数中出现的顺序无关,而是和声明派生类时基类出现的顺序相同。仍然以上面的 A、B、C、D 类为例,即使将 D 类构造函数写作下面的形式:

    D(形参列表): B(实参列表), C(实参列表), A(实参列表){
        //其他操作
    }
    

    那么也是先调用 A 类的构造函数,再调用 B 类构造函数,最后调用 C 类构造函数。

    下面是一个多继承的实例:

    #include <iostream>
    using namespace std;
    //基类
    class BaseA{
    public:
        BaseA(int a, int b);
        ~BaseA();
    protected:
        int m_a;
        int m_b;
    };
    BaseA::BaseA(int a, int b): m_a(a), m_b(b){
        cout<<"BaseA constructor"<<endl;
    }
    BaseA::~BaseA(){
        cout<<"BaseA destructor"<<endl;
    }
    //基类
    class BaseB{
    public:
        BaseB(int c, int d);
        ~BaseB();
    protected:
        int m_c;
        int m_d;
    };
    BaseB::BaseB(int c, int d): m_c(c), m_d(d){
        cout<<"BaseB constructor"<<endl;
    }
    BaseB::~BaseB(){
        cout<<"BaseB destructor"<<endl;
    }
    //派生类
    class Derived: public BaseA, public BaseB{
    public:
        Derived(int a, int b, int c, int d, int e);
        ~Derived();
    public:
        void show();
    private:
        int m_e;
    };
    Derived::Derived(int a, int b, int c, int d, int e): BaseA(a, b), BaseB(c, d), m_e(e){
        cout<<"Derived constructor"<<endl;
    }
    Derived::~Derived(){
        cout<<"Derived destructor"<<endl;
    }
    void Derived::show(){
        cout<<m_a<<", "<<m_b<<", "<<m_c<<", "<<m_d<<", "<<m_e<<endl;
    }
    int main(){
        Derived obj(1, 2, 3, 4, 5);
        obj.show();
        return 0;
    }
    

    运行结果:

    BaseA constructor
    BaseB constructor
    Derived constructor
    1, 2, 3, 4, 5
    Derived destructor
    BaseB destructor
    BaseA destructor
    

    从运行结果中还可以发现,多继承形式下析构函数的执行顺序和构造函数的执行顺序相反。

    多重继承下的命名冲突

    当两个或多个基类中有同名的成员时,如果直接访问该成员,就会产生命名冲突,编译器不知道使用哪个基类的成员。这个时候需要在成员名字前面加上类名和域解析符::,以显式地指明到底使用哪个类的成员,消除二义性。

    修改上面的代码,为 BaseA 和 BaseB 类添加 show() 函数,并将 Derived 类的 show() 函数更名为 display():

    #include <iostream>
    using namespace std;
    //基类
    class BaseA{
    public:
        BaseA(int a, int b);
        ~BaseA();
    public:
        void show();
    protected:
        int m_a;
        int m_b;
    };
    BaseA::BaseA(int a, int b): m_a(a), m_b(b){
        cout<<"BaseA constructor"<<endl;
    }
    BaseA::~BaseA(){
        cout<<"BaseA destructor"<<endl;
    }
    void BaseA::show(){
        cout<<"m_a = "<<m_a<<endl;
        cout<<"m_b = "<<m_b<<endl;
    }
    //基类
    class BaseB{
    public:
        BaseB(int c, int d);
        ~BaseB();
        void show();
    protected:
        int m_c;
        int m_d;
    };
    BaseB::BaseB(int c, int d): m_c(c), m_d(d){
        cout<<"BaseB constructor"<<endl;
    }
    BaseB::~BaseB(){
        cout<<"BaseB destructor"<<endl;
    }
    void BaseB::show(){
        cout<<"m_c = "<<m_c<<endl;
        cout<<"m_d = "<<m_d<<endl;
    }
    //派生类
    class Derived: public BaseA, public BaseB{
    public:
        Derived(int a, int b, int c, int d, int e);
        ~Derived();
    public:
        void display();
    private:
        int m_e;
    };
    Derived::Derived(int a, int b, int c, int d, int e): BaseA(a, b), BaseB(c, d), m_e(e){
        cout<<"Derived constructor"<<endl;
    }
    Derived::~Derived(){
        cout<<"Derived destructor"<<endl;
    }
    void Derived::display(){
        BaseA::show();  //调用BaseA类的show()函数
        BaseB::show();  //调用BaseB类的show()函数
        cout<<"m_e = "<<m_e<<endl;
    }
    int main(){
        Derived obj(1, 2, 3, 4, 5);
        obj.display();
        return 0;
    }
    
    注意第 6465 行代码,我们显式的指明了要调用哪个基类的 show() 函数。
    

    派生类对象中数据成员的排列形式

    在普通多继承方式下,若定义派生类对象,其中的数据成员的排列规则是:首先按照派生类定义形式中基类的排列顺序,将基类成员依次排列,接下来再存放派生类中新添加的数据,假设有如下代码:

    class Base1{    //定义基类Base1
    public:
        void func_base1();
    private:
        int n_base1;
        int m_base1;
    };
    class Base2{    //定义基类Base2
    public:
        void func_base2();
    private:
        int n_base2;
        int m_base2;
    };
    //定义派生类Derive,继承自Base1和Base2
    class Derive:public Base1, public Base2{
    public:
        void func_derive();
    private:
        int n_derive;
    };
    

    上述代码中,派生 Derive 继承自基类 Base1 和 Base2,若定义派生类对象,则其中的数据成员排列形式如下图所示。

    图 2 多重继承中派生类成员的排列形式

    由图 2 可以看出,对于派生类 Derive 的对象来说,它将基类 Base1 的成员排列在最前端,第二个基类 Base2 的数据紧随其后,派生类自身的成员在最后存放,这种排列方式,使得不同类型的指针变量访问数据时操作比较简单,只需要从起始址开始,改变固定的偏移量即可。

    更多相关内容
  • 主要介绍了java为什么不允许类多重继承却允许接口多重继承,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 本文实例讲述了C++实现的多重继承功能。分享给大家供大家参考,具体如下: 多重继承 1. 多重继承即一个类继承了多个基类的属性。 2. 多重继承下派生类的构造函数必须同时负责所有基类构造函数的调用, 3. 派生类构造...
  • 本文实例讲述了JavaScript实现多重继承的方法。分享给大家供大家参考,具体如下: 1. 定义一个空的父类构造函数,然后通过prototype的方式为该父类定义属性和方法 2. 定义一个空的子类的构造函数,然后将子类的原型...
  • python多重继承实例

    2020-12-23 19:46:57
    本文实例讲述了python多重继承用法,分享给大家供大家参考。具体实现方法如下: 1.mro.py文件如下: #!/usr/bin/python # Filename:mro.py class P1: def foo(self): print 'called P1-foo' class P2: def foo...
  • 正文 首先得说明的是,Python的类分为经典类 和 新式类 经典类是python2.2之前...2.经典类在类多重继承的时候是采用从左到右深度优先原则匹配方法的..而新式类是采用C3算法(不同于广度优先)进行匹配的 3.经典类是没有__
  • 分别声明Teacher(教师)类和Cadre(干部)类,采用多重继承方式由这两个类派生出新类Teacher_Cadre(教师兼干部)。要求:①在两个基类中都包含一部分相同名字的数据成员name(姓名),age(年龄)和成员函数...
  • 多重继承

    2021-05-17 16:25:10
    多重继承 多重继承派生类 除去一个类从一个基类派生,C++还支持一个派生类同时继承多个基类 1.多重继承派生类的定义 如果已经定义了多个基类,那么定义多重继承的派生类的形式为: class 派生类名:访问标号1 基类名1...

    多重继承

    多重继承派生类

    除去一个类从一个基类派生,C++还支持一个派生类同时继承多个基类

    1.多重继承派生类的定义

    如果已经定义了多个基类,那么定义多重继承的派生类的形式为:

    class 派生类名:访问标号1 基类名1,访问标号2 基类名2... { //类体
    	成员列表
    };
    
    class A { };
    class B : public A { }; //A-B
    class C : public A { }; //A-C
    class D : public B,public C { }; //B-D,C-D
    

    2.多重继承派生类的构造函数

    多重继承派生类的构造函数形式与单一继承时的构造函数形式基本相同,只是在派生类的构造函数初始化列表中调用多个基类构造函数。 一般形式为:

    派生类名(形式参数列表):基类名1(基类1构造函数实参列表),基类名2(基类2构造函数实参列表),
    					  ...,
    					  子对象名1(子对象1属类构造函数实参列表),
    					  ...,
    					  派生类初始化列表
    {
    	派生类初始化函数体
    }
    

    其调用顺序是:
    (1)调用基类构造函数,各个基类按定义时的次序先后调用;
    (2)调用子对象构造函数,各个子对象按声明时的次序先后调用;
    (3)执行派生类初始化列表;
    (4)执行派生类初始化函数体;

    例:多重继承举例

    #include<iostream>
    #include<string>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<vector> 
    using namespace std; 
    
    class Base1 {
    	private:
    		int b1;
    	public:
    		Base1() {
    			b1=0;
    			cout<<"默认构造Base1:"<<"b1="<<b1<<endl;
    		}
    		Base1(int i) {
    			b1=i;
    			cout<<"构造Base1:"<<"b1="<<b1<<endl;
    		}
    };
    
    class Base2 {
    	private:
    		int b2;
    	public:
    		Base2() {
    			b2=0;
    			cout<<"默认构造Base2:"<<"b2="<<b2<<endl;
    		}
    		Base2(int j) {
    			b2=j;
    			cout<<"构造Base2:"<<"b2="<<b2<<endl;
    		}
    };
    
    class Base3 {
    	public:
    		Base3() {
    			cout<<"默认构造Base3:"<<endl;
    		}
    };
    
    class Derive : public Base1,public Base2,public Base3 {
    	private:
    		Base1 memberBase1;
    		Base2 memberBase2;
    		Base3 memberBase3;
    	public:
    		Derive() {
    			cout<<"默认构造函数Derive."<<endl; 
    		}
    		Derive(int a,int b,int c,int d): Base1(a),Base2(b),memberBase1(c),memberBase2(d) {
    			cout<<"构造Derive."<<endl;
    		}
    };
    
    int main()
    {
    	cout<<endl<<"创建派生类对象obj1:"<<endl;
    	Derive obj1;
    	cout<<endl<<"创建派生类对象(1,2,3,4):"<<endl;
    	Derive obj2(1,2,3,4);
    	return 0;
    }
    

    运行结果:
    在这里插入图片描述

    二义性问题及名字支配规则

    1.二义性问题

    多重继承时,多个基类可能出现同名的成员。在派生类中如果使用一个表达式的含义能解释为可以访问多个基类的成员,则这种对基类成员的访问就是不确定的,称这种访问具有二义性。C++要求派生类对基类成员的访问必须是无二义性的

    例如:

    class A {
    	public:
    		void fun() { cout<<"a.fun"<<endl; }
    };
    class B {
    	public:
    		void fun() { cout<<"b.fun"<<endl; }
    		void gun() { cout<<"b.gun"<<endl; }
    };
    class C:public A,public B {
    	public:
    		void gun() { cout<<"c.gun"<<endl; } //重写gun()
    		void hun() { fun(); } //出现二义性
    };
    int main()
    {
    	C c,*p=&c;
    	return 0;
    }
    

    使用成员名限定可以消除二义性,例如:

    //成员名限定消除二义性
    c.A::fun();
    c.B::fun();
    p->A::fun();
    p->B::fun();
    

    基本形式为:

    对象名.基类名::成员名
    对象指针名->基类名::成员名
    

    2.名字支配规则

    C++对于在不同的作用域声明的名字,可见性原则是:如果存在两个或多个具有包含关系的作用域,外层声明了一个名字,而内层没有再次声明相同的名字,那么外层名字在内层可见;如果在内层声明了相同的名字,则外层名字在内层不可见,这时称内层名字隐藏(或覆盖)了外层名字,这种现象称为隐藏规则

    在类的派生层次结构中,基类的成员和派生类新增的成员都具有类作用域,二者的作用域是不同的:基类在外层,派生类在内层

    如果派生类声明了一个和基类成员同名的新成员,派生的新成员就覆盖了基类同名成员,直接使用成员名只能访问到派生类的成员

    如果派生类中声明了与基类成员函数同名的新函数,即使函数的参数不同,从基类继承的同名函数的所有重载形式也都会被覆盖

    如果要访问被覆盖的成员,就需要使用基类名和作用域限定运算符来限定

    派生类D中的名字N覆盖基类B中同名的名字N,称为名字支配规则。如果一个名字支配另一个名字,则二者之间不存在二义性,当选择该名字时,使用支配者的名字,如:

    c.gun(); //使用C::gun
    

    如果要使用被支配者的名字,则应使用成员名限定,例如:

    c.B::gun(); //使用B::gun
    

    虚基类

    C++提供虚基类(virtual base class)的机制,使得在继承间接共同基类时只保留一份成员
    在这里插入图片描述
    1.虚基类的定义

    虚基类是在派生类定义时,指定继承方式时声明的。声明虚基类的一般形式为:

    class 派生类名: virtual 访问标签 虚基类名,... { //类体
    	成员列表
    };
    

    需要注意,为了保证虚基类在派生类中只继承一次,应当在该基类的所有直接派生类中声明为虚基类。否则仍然会出现对基类的多次继承

    例:虚基类举例

    #include<iostream>
    #include<string>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<vector> 
    using namespace std; 
    
    class A { //声明为基类A
    	public:
    		A(int n) { //A类的构造函数 
    			nv=n;
    			cout<<"Member of A"<<endl;
    		} 
    		void fun() {
    			cout<<"fun of A"<<endl;
    		}
    	private:
    		int nv;
    };
    
    class B1: virtual public A { //声明A为虚基类 
    	public:
    		B1(int a):A(a) { //B1类的构造函数 
    			cout<<"Member of B1"<<endl;
    		}
    	private:
    		int nv1; 
    };
    
    class B2: virtual public A { //声明A为虚基类
    	public:
    		B2(int a):A(a) { //B2类的构造函数
    			cout<<"Member of B2"<<endl; 
    		} 
    	private:
    		int nv2;
    };
    
    class C: public B1,public B2 {
    	public:
    		//派生类的构造函数的成员初始化列表中必须列出对虚基类构造函数的调用
    		C(int a):A(a),B1(a),B2(a) {
    			cout<<"Member of C"<<endl;
    		}
    		void fund() {
    			cout<<"fun of C"<<endl;
    		}
    	private:
    		int nvd;
    };
    
    int main()
    {
    	C c1(1);
    	c1.fund();
    	c1.fun(); //不会产生二义性
    	return 0; 
    }
    

    2.虚基类的初始化

    如果在虚基类中定义了带参数的构造函数,而且没有定义默认构造函数,则在其所有派生类(包括直接派生和间接派生)中,都要通过构造函数的初始化表对虚基类进行初始化。例如:

    class A { public: A(int) { } }; //定义基类
    class B: virtual public A {
    	public:
    		B(int a):A(a) { } //对基类A初始化
    };
    class C: virtual public A {
    	public:
    		C(int a):A(a) { } //对基类A初始化
    };
    class D: public B,public C {
    	public:
    		D(int a):A(a),B(a),C(a) { }
    };
    

    在最后的派生类中不仅要负责对其直接基类进行初始化,还要负责对虚基类初始化

    关于虚基类的说明:

    (1)一个类可以在一个类族中即被用作虚基类,也被用作非虚基类

    (2)派生类的构造函数的成员初始化列表中必须列出对虚基类构造函数的调用;如果未列出,则表示使用该虚基类的默认构造函数

    (3)在一个成员初始化列表中同时出现对虚基类和非虚基类构造函数的调用时,虚基类的构造函数先于非虚基类的构造函数执行

    多重继承应用举例

    #include<iostream>
    #include<string>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<vector> 
    using namespace std; 
    
    enum Color { //颜色枚举类型 
    	Red,Yellow,Green,White
    };
    
    class Circle { //圆类Circle的定义
    	private:
    		float radius;
    	public:
    		Circle(float r) {
    			radius=r;
    			cout<<"Circle initialized!"<<endl;
    		} 
    		~Circle() {
    			cout<<"Circle destroyed!"<<endl;
    		}
    		float Area() {
    			return 3.1415926*radius*radius;
    		}
    };
    
    class Table { //桌子类Table的定义
    	private:
    		float height;
    	public:
    		Table(float h) {
    			height=h;
    			cout<<"Table initialized!"<<endl;
    		}
    		~Table() {
    			cout<<"Table destroyed!"<<endl;
    		}
    		float Height() {
    			return height;
    		}
    };
    
    class RoundTable: public Table,public Circle { //圆卓类的定义
    	private:
    		Color color;
    	public:
    		RoundTable(float h,float r,Color c);
    		int GetColor() {
    			return color;
    		}
    		~RoundTable() {
    			cout<<"RoundTable destroyed!"<<endl;
    		}
    };
    
    RoundTable::RoundTable(float h,float r,Color c):Table(h),Circle(r) { //圆桌构造函数的定义
    	color=c;
    	cout<<"RoundTable initialized!"<<endl; 
    }
    
    int main()
    {
    	RoundTable cir_table(15.0,2.0,Yellow);
    	cout<<"The table properties are:"<<endl;
    	cout<<"Height="<<cir_table.Height()<<endl; //调用Table类的成员函数
    	cout<<"Area="<<cir_table.Area()<<endl; //调用circle类的成员函数
    	cout<<"Color="<<cir_table.GetColor()<<endl; //调用RoundTable 类的成员函数
    	return 0;
    }
    

    运行结果:
    在这里插入图片描述

    展开全文
  • 类的继承到多重继承详解以及如何使用super继承和issubclass()的使用继承issubclass()多重继承和super()多重继承super() 继承和issubclass()的使用 继承 继承就像是父与子的关系,子类可以从父类内里拿到相同的属性...
  • 多型· JavaScript和TypeScript的动态多重继承。 没有mixins。 Polytype是一个库,它以简单的语法为JavaScript和TypeScript添加了对动态支持。 “动态”意味着在运行时对基类的更改会立即反映在所有派生类中,就像...
  • 本文实例讲述了Python多重继承的方法解析执行顺序。分享给大家供大家参考,具体如下: 任何实现多重继承的语言都要处理潜在的命名冲突, 这种冲突由不相关的祖先类实现同名方法引起 class A: def say(self): ...
  • Lua多重继承代码实例

    2020-09-22 05:00:34
    主要介绍了Lua多重继承代码实例,本文直接给出实例代码,需要的朋友可以参考下
  • python和C++一样,支持多继承。概念虽然容易,但是困难的工作是如果子类调用一个自身没有定义的属性,它是按照何种顺序去到父类寻找呢,尤其是众多父类中有多个都包含该同名属性。 对经典类和新式类来说,属性的查找...
  • C++习题 多重继承

    2016-07-07 12:59:31
    c++多重继承的一个习题
  • 定义一个Person 类,结构如下图,为该类添加输入输出流运算符重载。Person 类以Public方式派生出一个Teacher类,数据成员包括:int gh(工号);char* title(职称),为该类添加输入输出流运算符重载,完成有参、无参、...
  • 多重继承(6_7钻石继承问题)多重继承(6_6)多重继承(6_7钻石继承问题)多重继承(6_6)
  • super()函数可以用于继承父类的方法,语法如下: super(type[, object-or-type]) 虽然super()函数的使用比较简单,但是需要根据单继承和多继承来分析函数的调用关系。 首先,当类之间的继承关系为单继承时,函数调用...
  • 今天小编就为大家分享一篇解决python super()调用多重继承函数的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • C++ 多重继承

    2021-01-20 13:39:42
    注意:多重继承在实际开发中尽量少用,能不用就不用。多重继承很繁杂,很复杂。 多重继承就是派生类继承多个基类,继承方法和一个继承是一样的。 一个继承请看我 —> “C++ 继承和派生” 文章,会有详细介绍。 链接:...
  • 主要介绍了C++中的多态与多重继承实现与Java的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 本文以实例形式较为全面的讲述了C++的多重继承与虚继承,是大家深入学习C++面向对象程序设计所必须要掌握的知识点,具体内容如下: 一、多重继承 我们知道,在单继承中,派生类的对象中包含了基类部分 和 派生类...
  • 钻石继承与 ES6 代理。 在撰写本文时仅适用于 Firefox。 $ npm install lozenge 用法 class Worker { help ( ) { console . log ( ` ${ this . name } is helping` ) ; } } class Person { say ( ) { console ...
  • 九头蛇 Android 风格的多继承项目。
  • 在python中一个类能继承自不止一个父类,这叫做python的多重继承(Multiple Inheritance )。 语法 class SubclassName(BaseClass1, BaseClass2, BaseClass3, …): pass 菱形继承 在多层继承和多继承同时使用的...
  • 多继承和多重继承

    千次阅读 2021-03-08 16:19:32
    ------------------siwuxie095多继承 和 多重继承,两个词差别不大,但是差之毫厘、谬以千里 …多重继承如果有这样三个类:人类、士兵类、步兵类,其中:士兵类继承了人类,步兵类继承了士兵类,这三个类之间的关系...

    ------------------siwuxie095

    多继承 和 多重继承,两个词差别不大,但是差之毫厘、谬以千里 …

    多重继承

    如果有这样三个类:人类、士兵类、步兵类,其中:士兵类继承了人类,

    步兵类继承了士兵类,这三个类之间的关系称之为多重继承

    35dd1b4910c690ffb39c0d846d389af4.png

    如果在继承时,这三个类都使用了 public 公有继承,那么它们也

    存在着以下的关系:

    士兵是一个人,步兵是一个士兵,步兵也是一个人

    f87c343a299afda5873a8e115c190e6a.png

    具体到代码上,可以这样来写:

    ba5d4f34dbafb720d537409a56b7282f.png

    多继承

    如果有一个类,不仅继承了工人类,还继承了农民类,暂且把这个类

    称之为 农民工类

    即 一个子类同时有两个父类,或 一个派生类同时有两个基类,这样的

    关系称之为多继承

    fa23007637174b2c70b3b857f2ee68c9.png

    多继承和多重继承是完全不同的,在多继承的关系下,如果农民工类

    在继承工人类和农民类时,都以 public 公有继承的方式继承,那么

    它们还存在着这样一种关系:

    农民工是一个工人,农民工是一个农民,但工人和农民本身是平行的

    618b04dc8f52abde1eda12db0c1f9ac1.png

    具体到代码上,可以这样来写:

    cba105a2caa8fd138f6159b27792f62c.png

    注意:写法上,中间要加逗号隔开,在继承每一个类时,都要将继承

    方式写出来,如果不写,系统默认继承方式为 private 私有继承

    程序 1:多重继承

    Person.h:

    #include

    using namespacestd;

    classPerson

    {

    public:

    Person(string name = "Jim");

    ~Person();

    voidplay();

    protected:

    string m_strName;

    };

    Person.cpp:

    #include"Person.h"

    #include

    using namespacestd;

    Person::Person(string name)

    {

    m_strName = name;

    cout << "Person()"<< endl;

    }

    Person::~Person()

    {

    cout << "~Person()"<< endl;

    }

    voidPerson::play()

    {

    cout << "Person--play()"<< endl;

    cout << m_strName << endl;

    }

    Soldier.h:

    #include"Person.h"

    classSoldier:publicPerson

    {

    public:

    Soldier(string name = "James", intage = 20);

    ~Soldier();

    voidwork();

    protected:

    intm_iAge;

    };

    Soldier.cpp:

    #include"Soldier.h"

    #include

    using namespacestd;

    Soldier::Soldier(string name, intage)

    {

    m_strName = name;

    m_iAge = age;

    cout << "Soldier()"<< endl;

    }

    Soldier::~Soldier()

    {

    cout << "~Soldier()"<< endl;

    }

    voidSoldier::work()

    {

    cout << "Soldier--work()"<< endl;

    cout << m_strName << ","<< m_iAge << endl;

    }

    Infantry.h:

    #include"Soldier.h"

    classInfantry:publicSoldier

    {

    public:

    Infantry(string name = "Jack", intage = 30);

    ~Infantry();

    voidattack();

    };

    Infantry.cpp:

    #include"Infantry.h"

    #include

    using namespacestd;

    Infantry::Infantry(string name, intage)

    {

    m_strName = name;

    m_iAge = age;

    cout << "Ifantry()"<< endl;

    }

    Infantry::~Infantry()

    {

    cout << "~Infantry()"<< endl;

    }

    voidInfantry::attack()

    {

    cout << "Infantry--attack()"<< endl;

    cout <

    }

    main.cpp:

    #include

    #include"Infantry.h"

    #include

    using namespacestd;

    voidtest1(Person p)

    {

    p.play();

    }

    voidtest2(Person &p)

    {

    p.play();

    }

    voidtest3(Person *p)

    {

    p->play();

    }

    //无论继承的层级有多少,只要保持着直接或间接的继承关系,

    //子类都可以与自己的直接父类或间接父类称为is-a关系

    //并且能够通过指针对直接子类或间接子类的对象进行相应的操作

    intmain(void)

    {

    Infantry infantry;

    cout << endl;

    infantry.play();

    infantry.work();

    infantry.attack();

    cout << endl;

    test1(infantry);

    cout << endl;

    test2(infantry);

    cout << endl;

    test3(&infantry);

    system("pause");

    return0;

    }

    运行一览:

    7ab7c567a9b0f7d4371ae0be8f48e705.png

    程序 2:多继承

    Farmer.h:

    #include

    using namespacestd;

    classFarmer

    {

    public:

    Farmer(string name = "Jack");

    virtual~Farmer();//虚析构函数

    voidsow();

    protected:

    string m_strName;

    };

    Farmer.cpp:

    #include"Farmer.h"

    #include

    using namespacestd;

    Farmer::Farmer(string name)

    {

    m_strName = name;

    cout << "Farmer()"<< endl;

    }

    Farmer::~Farmer()

    {

    cout << "~Farmer()"<< endl;

    }

    voidFarmer::sow()

    {

    cout << "Farmer--sow()"<< endl;

    cout << m_strName << endl;

    }

    Worker.h:

    #include

    using namespacestd;

    classWorker

    {

    public:

    Worker(string code = "001");

    virtual~Worker();//虚析构函数

    voidwork();

    protected:

    string m_strCode;

    };

    Worker.cpp:

    #include"Worker.h"

    #include

    using namespacestd;

    Worker::Worker(string code)

    {

    m_strCode = code;

    cout << "Worker()"<< endl;

    }

    Worker::~Worker()

    {

    cout << "~Worker()"<< endl;

    }

    voidWorker::work()

    {

    cout << "Worker--work()"<< endl;

    cout << m_strCode << endl;

    }

    MigrantWorker.h:

    #include"Farmer.h"

    #include"Worker.h"

    classMigrantWorker :publicFarmer, publicWorker

    {

    public:

    MigrantWorker(string name, string code);

    virtual~MigrantWorker();

    };

    MigrantWorker.cpp:

    #include"MigrantWorker.h"

    #include

    using namespacestd;

    //使用初始化列表初始化

    MigrantWorker::MigrantWorker(string name, string code) :Farmer(name), Worker(code)

    {

    cout << "MigrantWorker()"<< endl;

    }

    MigrantWorker::~MigrantWorker()

    {

    cout << "~MigrantWorker()"<< endl;

    }

    main.cpp:

    #include

    #include"MigrantWorker.h"

    #include

    using namespacestd;

    intmain(void)

    {

    //从堆中实例化子类对象,先调用父类构造函数再调用子类构造函数

    //调用父类构造函数的顺序和初始化列表中的顺序一样

    //析构函数的调用顺序则相反

    MigrantWorker *p = newMigrantWorker("Merry", "100");

    cout << endl;

    p->sow();

    p->work();

    cout << endl;

    deletep;

    p = NULL;

    system("pause");

    return0;

    }

    运行一览:

    c59131ea477600ac370169c6e1b15420.png

    【made by siwuxie095】

    展开全文
  • VC 实现C 类的多重继承,cout(1,1,2008,11,12,12);//直接使用DateTimeType构造函数设置日期时间  cout();//显示时间日期  dt.SetDate(8,8,2008);//调用基类的成员函数修改日期  dt.SetTime(20,8,8);//调用基类...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 131,179
精华内容 52,471
关键字:

多重继承