精华内容
下载资源
问答
  • 多继承可以看作是单继承的扩展。所谓多继承派生类具有个基类,派生类..本文将对C++多继承同名隐藏实例进行分析
  • C++学习之继承篇(多继承与多重继承

    万次阅读 多人点赞 2016-01-21 18:55:41
    多继承一个子类继承多个父类。多继承对父类的个数没有限制,继承方式可以是公共继承、保护继承和私有继承, 不写继承方式,默认是private继承 多继承举例: #include #include #include using ...

    1.多继承

    多继承是指一个子类继承多个父类。多继承对父类的个数没有限制,继承方式可以是公共继承、保护继承和私有继承,

    不写继承方式,默认是private继承


    多继承举例:

    #include <iostream>
    #include <stdlib.h>
    #include <string>
    using namespace std;


    /**
     * 定义工人类: Worker
     * 数据成员: m_strName
     * 成员函数: work()
     */
    class Worker
    {
    public:
        Worker(string name)
    {
    m_strName = name;
    cout << "Worker" << endl;
    }
    virtual ~Worker()
    {
    cout << "~Worker" << endl;
    }
    void work()
    {
    cout << m_strName << endl;
    cout << "work" << endl;
    }
    protected:
    string m_strName;
    };


    /**
     * 定义儿童类: Children
     * 数据成员: m_iAge
     * 成员函数: play()
     */
    class Children
    {
    public:
    Children(int age)
    {
    m_iAge = age;
    cout << "Children" << endl;
    }
    ~Children()
    {
    cout << "~Children" << endl;
    }
    void play()
    {
    cout << m_iAge << endl;
    cout << "play" << endl;
    }
    protected:
    int m_iAge;
    };



    /**
     * 定义童工类: ChildLabourer
     * 公有继承工人类和儿童类
     */
    class ChildLabourer :public Worker,public Children
    {
    public:
    ChildLabourer(string name, int age):Worker(name),Children(age)
    {
    cout << "ChildLabourer" << endl;
    }


    ~ChildLabourer()
    {
    cout << "~ChildLabourer" << endl;
    }
    };


    int main(void)
    {
        // 使用new关键字创建童工类对象
    Worker * p = new ChildLabourer("jack",14);
        // 通过童工对象调用父类的work()和play()方法
    p->work();
       // p->play();
        // 释放
        delete p;
        p = NULL;


    return 0;
    }

    输出结果:

    Worker
    Children
    ChildLabourer
    jack
    work
    ~ChildLabourer
    ~Children
    ~Worker
    由输出结果可以看出,在多继承中,任何父类的指针都可以指向子类的对象,在实例化子类时,先根据继承的顺序依次调用父类的构造函数,然后再调用该子类自己的构造函数;
    用delete销毁该基类对象时,如果该基类的析构函数不是虚析构函数,且该基类的继承顺序在第一个,如上面的Worker类,(class ChildLabourer :public Worker,public Children)那么delete 父类的时候只会调用父类Worker的析构函数,系统不会出错,但是如果继承的时候顺序不是在第一位(class ChildLabourer :public Children,public Worker),就会报内存泄露的错误,如下图所示,如果父类的析构函数是虚析构函数,那么销毁的时候会先调用子类的析构函数再调用所有父类的析构函数,注意,此时,子类的父类的析构函数都会被调用!!!


    2.多重继承

    多重继承特点总结如下:

    (1)多重继承与多继承不同,当B类从A类派生,C类从B类派生,此时称为多重继承

    (1)当实例化子类时,会首先依次调用所有基类的构造函数,最后调用该子类的构造函数;销毁该子类时,则相反,先调用该子类的析构函数,再依次调用所有基类的析构函数。

    (2)无论继承的层级有多少层,只要它们保持着直接或间接的继承关系,那么子类都可以与其直接父类或间接父类构成 is a的关系,并且能够通过父类的指针对直接子类或间接子类进行相应的操作,子类对象可以给直接父类或间接父类的对象或引用赋值或初始化。




    展开全文
  • C++多继承

    万次阅读 2008-04-18 17:58:00
    所谓多继承派生类具有个基类,派生类与每个基类之间的关系仍可看作是一个单继承。 多继承下派生类的定义格式如下: class :,,… { }; 其中,,,…是三种继承方式:public、private、pr
     

    上午的时候,重温C++ 多继承问题,看到一篇文章,感觉不错,所以转下,以备份,分享!

    多继承可以看作是单继承的扩展。所谓多继承是指派生类具有多个基类,派生类与每个基类之间的关系仍可看作是一个单继承。

     
      多继承下派生类的定义格式如下:
     
      class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…
       {
        <派生类类体>
       };
     
      其中,<继承方式1>,<继承方式2>,…是三种继承方式:public、private、protected之一。例如:
     
    class A
    {
    };
    class B
    {
    };
    class C : public A, public B
    {
    };
     
     
    其中,派生类C具有两个基类(类A和类B),因此,类C是多继承的。按照继承的规定,派生类C的成员包含了基类A, B中成员以及该类本身的成员。
     
      多继承的构造函数
     
      在多继承的情况下,派生类的构造函数格式如下:
     
      <派生类名>(<总参数表>):<基类名1>(<参数表1>),<基类名2>(<参数表2>),…
       <子对象名>(<参数表n+1>),…
        {
         <派生类构造函数体>
        }
     
      其中,<总参数表>中各个参数包含了其后的各个分参数表。
     
      多继承下派生类的构造函数与单继承下派生类构造函数相似,它必须同时负责该派生类所有基类构造函数的调用。同时,派生类的参数个数必须包含完成所有基类初始化所需的参数个数。
     
      派生类构造函数执行顺序是先执行所属基类的构造函数,再执行派生类本身构造函数,处于同一层次的各基类构造函数的执行顺序取决于定义派生类时所指定的各基类顺序,与派生类构造函数中所定义的成员初始化列表的各项顺序无关。也就是说,执行基类构造函数的顺序取决于定义派生类时基类的顺序。可见,派生类构造函数的成员初始化列表中各项顺序可以任意地排列。
     
      下面通过一个例子来说明派生类构造函数的构成及其执行顺序。
     
    #include <iostream.h>
    class B1
    {
    public:
           B1(int i)
           {
                  b1 = i;
                  cout<<"构造函数 B1."<<i<< endl;
           }
           void print()
           {
                  cout<<"B1.print()"<<b1<<endl;
           }
    private:
           int b1;
    };
     
    class B2
    {
    public:
           B2(int i)
           {
                  b2 = i;
                  cout<<"构造函数 B2."<<i<< endl;
           }
           void print()
           {
                  cout<<"B2.print()"<<b2<<endl;
           }
    private:
           int b2;
    };
    class B3
    {
    public:
           B3(int i)
           {
                  b3 = i;
                  cout<<"构造函数 B3."<<i<<endl;
           }
           int getb3()
           {
                  return b3;
           }
    private:
           int b3;
    };
    class A : public B2, public B1
    {
    public:
           A(int i, int j, int k, int l):B1(i), B2(j), bb(k)
           {
                  a = l;
                  cout<<"构造函数 A."<<a<<endl;
           }
           void print()
           {
                  B1::print();
                  B2::print();
                  cout<<"A.print()"<<a<<","<<bb.getb3()<<endl;
           }
    private:
           int a;
           B3 bb;
    };
    void main()
    {
           A aa(1, 2, 3, 4);
           aa.print();      
    }
      该程序的输出结果为:
     
       构造函数 B2.2
     
       构造函数 B1.1
     
       构造函数 B3.3
     
       构造函数 A.4
     
       B1.print().1
     
       B2.print()2
     
       A.print()4, 3
     
      在该程序中,作用域运算符::用于解决作用域冲突的问题。在派生类A中的print()函数的定义中,使用了B1::print;和B2::print();语句分别指明调用哪一个类中的print()函数,这种用法应该学会。
     
    二义性问题
     
      一般说来,在派生类中对基类成员的访问应该是唯一的,但是,由于多继承情况下,可能造成对基类中某成员的访问出现了不唯一的情况,则称为对基类成员访问的二义性问题。
     
      实际上,在上例已经出现过这一问题,回忆一下上例中,派生类A的两基类B1和B2中都有一个成员函数print()。如果在派生类中访问print()函数,到底是哪一个基类的呢?于是出现了二义性。但是在上例中解决了这个问题,其办法是通过作用域运算符::进行了限定。如果不加以限定,则会出现二义性问题。
     
      下面再举一个简单的例子,对二义性问题进行深入讨论。例如:
     
    class A
    {
    public:
           void f();
    };
    class B
    {
    public:
           void f();
           void g();
    };
    class C : public A, public B
    {
    public:
           void g();
           void h();
    };
     
      如果定义一个类C的对象c1:
     
       C c1;
     
      则对函数f()的访问
     
       c1.f();
     
      便具有二义性:是访问类A中的f(),还是访问类B中的f()呢?
     
      解决的方法可用前面用过的成员名限定法来消除二义性,例如:
     
       c1.A::f();
     
      或者
     
       c1.B::f();
     
      但是,最好的解决办法是在类C中定义一个同名成员f(),类C中的f()再根据需要来决定调用A::f(),还是B::f(),还是两者皆有,这样,c1.f()将调用C::f()。
     
      同样地,类C中成员函数调用f()也会出现二义性问题。例如:
     
      viod C::h()
       {
        f();
       }
     
      这里有二义性问题,该函数应修改为:
     
       void C::h()
       {
        A::f();
       }
     
      或者
     
       void C::h()
       {
        B::f();
       }
     
      或者
     
       void C::f()
       {
        A::f();
        B::f();
       }
     
      另外,在前例中,类B中有一个成员函数g(),类C中也有一个成员函数g()。这时,
     
       c1.g();
     
      不存在二义性,它是指C::g(),而不是指B::g()。因为这两个g()函数,一个出现在基类B,一个出现在派生类C,规定派生类的成员将支配基类中的同名成员。因此,上例中类C中的g()支配类B中的g(),不存在二义性,可选择支配者的那个名字。
     
      当一个派生类从多个基类派生类,而这些基类又有一个共同的基类,则对该基类中说明的成员进行访问时,也可能会出现二义性。例如:
     
    class A
    {
    public:
           int a;
    };
    class B1 : public A
    {
    private:
           int b1;
    };
    class B2 : public A
    {
    private:
           int b2;
    };
    class C : public B1, public B2
    {
    public:
           int f();
    private:
           int c;
    };
      已知:C c1;
     
      下面的两个访问都有二义性:
     
      c1.a;
      c1.A::a;
     
      而下面的两个访问是正确的:
     
      c1.B1::a;
      c1.B2::a;
     
      类C的成员函数f()用如下定义可以消除二义性:
     
      int C::f()
       {
        retrun B1::a + B2::a;
       }
     
      由于二义性的原因,一个类不可以从同一个类中直接继承一次以上,例如:
     
      class A : public B, public B
       {
        …
       }
      这是错误的。
    展开全文
  • 继承的概念:继承是指类与类之间的继承关系 ,子类继承父类,子类可以将父类的属性方法继承下来,现实生活中继承指的是对象与对象的继承关系,程序间的继承是指类与类之间的继承关系。继承关系的梳理:A类是B类(is ...
    继承的概念继承是指类与类之间的继承关系 ,子类继承父类,子类可以将父类的属性方法继承下来,现实生活中继承指的是对象与对象的继承关系,程序间的继承是指类与类之间的继承关系。继承关系的梳理:A类是B类(is a),如果这样能够说通,则两个类就可以建立继承关系。以下代码是了车类与出租车类 共同继承了Car属性 
    
    
    
    
    
    
    
    
    
    展开全文
  • Java中的多继承

    千次阅读 2016-05-23 19:06:13
    Java中多继承的两种实现方式

    多继承是指一个类继承多个类的特性。Java中一般情况之下都只支持单继承,因为单继承是有单继承的好处的,安全性比较高,所以在Java中单继承的使用时比较多的,或者说除了必须使用多继承以外都得使用单继承。但是多继承也是必须有的,接口和内部类就提供了多继承的思想。

    【1】接口

    抽象类中子类只能继承一个父类,但是却可以实现多个接口。为什么接口可以多继承的原因是在接口中没有任何具体的方法的实现,所以不会存在冲突的问题。

    package TwoWeek;
    // 接口的方式实现多继承
    public class MulTest1 {
    	public static void main(String args[]){
    		Son son = new Son();
    		son.eat();              // 儿子吃饭
    		son.strong();		// 我很强壮
    		son.beautiful();	// 我很漂亮
    		son.fight();		// 会打架
    	}
    	
    }
    // 父亲接口
    interface Father{
    	void strong();
    	void fight();
    }
    // 母亲接口
    interface Mother{
    	void beautiful();
    }
    
    class Character{
    	public void eat(){
    		// 这个函数可以在下面被覆写
    		System.out.println("吃饭");
    	}
    	public void fight(){
    		// 这个方法父类实现了,子类就不需要实现了
    		System.out.println("会打架");
    	}
    }
    
    // 实现了多继承同时也是继承喝接口的联合使用
    class Son extends Character implements Father, Mother{
    	public void eat(){
    		// 可以覆写上边的方法
    		System.out.println("儿子吃饭");
    	}
    	public void strong(){
    		System.out.println("我很强壮");
    	}
    	public void beautiful(){
    		System.out.println("我很漂亮");
    	}
    

    【2】内部类

    使用接口的方式固然很好,但是其是具有局限性的。如果我已经定义好了一些抽象类或者具体类,不想将其转变成接口,那只能是采用内部类的方式了实现了。其实内部类的实现方式也很强大。

    package TwoWeek;
    // 使用内部类的方式实现多继承
    public class MulTest2 {
    	public static void main(String args[]){
    		Son2 son = new Son2();
    		System.out.println(son.getStrong());
    		System.out.println(son.getBeautiful());
    	}
    }
    
    class Father2 {  
        public int strong(){  
            return 9;  
        }    
    }  
      
    class Mother2 {  
        public int beautiful(){  
            return 8;  
        }  
    }  
    class Son2{
    	class FatherInner extends Father2{
    		public int strong(){
    			return super.strong()+1;
    		}
    	}
    	// 在继承的基础之上加上自己的属性
    	class MotherInner extends Mother2{
    		public int beautiful(){
    			return super.beautiful()+1;
    		}
    	}
    	
    	public int getStrong(){
    		return new FatherInner().strong();
    	}
    	
    	public int getBeautiful(){
    		return new MotherInner().beautiful();
    	}
    }


    展开全文
  • 多重继承多继承 这个我们来讲讲这两个的概念问题,一字之差,千差万别。 多重继承,比如有三个类,人类-士兵类-步兵类,三个依次继承,这样的继承称为多重继承。class Person {};class Soldier :public Person {...
  • 继承

    千次阅读 2019-05-06 22:06:57
    继承:从已有类中,派生出新的类,新的类中吸收已有类当中的状态和行为,并能扩展出新的能力。 Java继承是使用已有类作为基础,建立新的类。 继承的格式: class 父类{} class 子类 extends 父类 1、继承只允许多层...
  • c++多继承二义性的另类解决办法

    千次阅读 2010-05-11 12:11:00
    所谓多继承派生类具有个基类,派生类与每个基类之间的关系仍可看作是一个单继承。 多继承下派生类的定义格式如下: class :,,… { }; 其中,,,…是三种继承方式:public、private、protected之一。例如:...
  • 继承的基本概念:继承指一个对象直接使用另一对象的属性和方法   继承的作用:继承是面向对象语言的重要机制。借助继承,可以扩展原有的代码,应用到其他程序中,而不必重新编写这些代码。 在java语言中,继承是...
  • Java 实现“多继承

    万次阅读 多人点赞 2019-07-20 12:49:19
    一、Java语言特点 Java是一种简单、面向对象、分布式、易读、鲁棒、安全、结构明晰、可移植、高性能、线程、动态的语言。...多继承一个子类同时继承多个父类,从而具备个父类的特征 多继承会造成 ...
  • java是单继承

    千次阅读 2016-04-05 15:00:47
    继承一个子类最多只能有一个父类。 多继承是一个子类可以有二个以上的父类。 由于多继承会带来二义性,Java语言中的类只支持单继承,而接口支持多继承。 Java中多继承的功能是通过接口(interface)来间接...
  • 继承的概念:继承机制:可以利用已有的数据类型来定义新的数据类型,所定义的新的数据类型不仅拥有新定义的成员,而且还同时拥有旧的成员。OOP强调软件的可重用性(software reuseablility).C++提供类的继承机制,...
  • 多继承原理详解及实例分析

    千次阅读 2016-03-17 11:56:10
    多继承原理详解及实例分析
  • 1、java 与 C++ 的不同点在于多继承。 Java:不能多继承,只能单继承,但可以实现个接口 C++:可以实现多继承。 例如: class A extends B implements C,D,E {} 2、如若写成 interface A extends B,C,D 可以...
  • c++ 多层继承分析

    千次阅读 2018-02-02 18:02:03
    (1)首先我们考虑一个(非虚拟)多重继承的相对简单的例子。看看下面的C++类层次结构: 注意Top被继承了两次(在Eiffel语言中这被称作重复继承)。 这意味着类型Bottom的一个实例bottom将有两个叫做a的元素(分别...
  • java为什么不支持多继承

    千次阅读 2015-06-23 15:56:16
    多继承指一个子类能同时继承于个父类,从而同时拥有个父类的特征,但缺点是显著的。  1.若子类继承的父类中拥有相同的成员变量,子类在引用该变量时将无法判别使用哪个父类的成员变量。如:  public ...
  • Java为什么不支持多继承

    千次阅读 2014-07-17 10:33:12
    多继承指一个子类能同时继承于个父类,从而同时拥有个父类的特征,但缺点是显著的。 1.若子类继承的父类中拥有相同的成员变量,子类在引用该变量时将无法判别使用哪个父类的成员变量。如: public class classA ...
  • 继承 是面向对象编程中的一种技术,是一个指定的基类,在继承体系结构中,将其成员数据实例共享给也从这个基类型直接或间接派生的其它类。形式:在继承定义中包含了virtual关键字的继承关系,如下图中,类A就...
  • C++继承

    千次阅读 多人点赞 2020-06-06 19:45:20
    C++继承 1.继承的概念及定义 1.1继承的概念 继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象...
  • 2. 什么是继承?多重继承

    千次阅读 2019-12-26 09:01:06
    2.1 继承与多态 2.1.1 父类与子类: 对象既具有共同性,也具有特殊性。运用抽象的原则舍弃对象的特殊性,抽取其共同...java 的继承性是子类对象拥有其父类的全部属性与方法。 就像我们常说的血脉一样,华夏儿女的...
  • python中使用多继承问题和super()内置函数的使用1、python中使用多继承问题python中使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承,也叫菱形继承问题)等1.1、MRO简介:MRO即方法解析顺序(method ...
  • 9.多继承与类模板

    万次阅读 2020-03-26 01:05:43
    多重继承、虚基类、虚继承3.类继承-派生类访问基类的友元4.类模板 1.多态–虚函数 C++中序函数表位于只读数据段(.rodata),也就是C++内存模型中的常量区; 而序函数则位于代码段(.text),也就是C++内存模型中的代码区;...
  • C++ 继承

    千次阅读 2021-03-23 20:32:55
    继承:在定义一个新的类 B 时,如果该类与某个已有的类 A 相似,的是 B 拥有 A 的全部特点,在属性上 A 是 B 的子集;那么就可以把 A 作为一个基类,而把 B 作为基类的一个派生类也称为子类。 派生类:派生类是...
  • 多继承比单继承更复杂,引入了歧义的问题,以及虚继承的必要性; 虚继承在大小,速度,初始化,复制的复杂性上有不小的代价,当虚基类中没有数据时还是比较合适的; 多继承有时也是有用的。典型的场景是:public继承...
  • C++多态虚函数表详解(多重继承多继承情况)

    万次阅读 多人点赞 2018-08-20 16:51:00
    多继承一个类同时继承个基类,假设这些基类都有虚函数,也就是说每个基类都有虚函数表,那么该子类的逻辑结果和虚函数表是什么样子呢? class ClassA1 { public: ClassA1() { cout ()" ; } virtual ~...
  • 多重继承和单重继承

    千次阅读 2017-03-12 17:03:40
    多重继承(Multiple Inheritance, MI)指的是一个类别可以同时从多于一个父类继承行为与特征的功能。与单一继承相对,单一继承指一个类别只可以继承自一个父类。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 497,217
精华内容 198,886
关键字:

多继承是指