zoukankan      html  css  js  c++  java
  • C++学习19 类的多继承

    在前面的例子中,派生类都只有一个基类,称为单继承。除此之外,C++也支持多继承,即一个派生类可以有两个或多个基类。

    多继承容易让代码逻辑复杂、思路混乱,一直备受争议,中小型项目中较少使用,后来的 Java、C#、PHP 等干脆取消了多继承。想快速学习C++的读者可以不必细读。

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

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

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

    多继承下的构造函数

    多继承派生类的构造函数和单继承类基本相同,只是要包含多个基类构造函数。如:

    D类构造函数名(总参数表列): A构造函数(实参表列), B类构造函数(实参表列), C类构造函数(实参表列){
        新增成员初始化语句
    }

    各基类的排列顺序任意。

    派生类构造函数的执行顺序同样为:先调用基类的构造函数,再调用派生类构造函数。基类构造函数的调用顺序是按照声明派生类时基类出现的顺序。

    下面的定义了两个基类,BaseA类和BaseB类,然后用多继承的方式派生出Sub类。

    #include <iostream>
    using namespace std;
    //基类
    class BaseA{
    protected:
        int a;
        int b;
    public:
        BaseA(int, int);
    };
    BaseA::BaseA(int a, int b): a(a), b(b){}
    //基类
    class BaseB{
    protected:
        int c;
        int d;
    public:
        BaseB(int, int);
    };
    BaseB::BaseB(int c, int d): c(c), d(d){}
    //派生类
    class Sub: public BaseA, public BaseB{
    private:
        int e;
    public:
        Sub(int, int, int, int, int);
        void display();
    };
    Sub::Sub(int a, int b, int c, int d, int e): BaseA(a, b), BaseB(c, d), e(e){}
    void Sub::display(){
        cout<<"a="<<a<<endl;
        cout<<"b="<<b<<endl;
        cout<<"c="<<c<<endl;
        cout<<"d="<<d<<endl;
        cout<<"e="<<e<<endl;
    }
    int main(){
        (new Sub(1, 2, 3, 4, 5)) -> display();
        return 0;
    }

    从基类BaseA和BaseB继承来的成员变量,在 Sub::display() 中都可以访问。

    命名冲突

    当两个基类中有同名的成员时,就会产生命名冲突,这时不能直接访问该成员,需要加上类名和域解析符。

    假如在基类BaseA和BaseB中都有成员函数 display(),那么下面的语句是错误的:

    Sub obj;
    obj.display();

    由于BaseA和BaseB中都有display(),系统将无法判定到底要调用哪一个类的函数,所以报错。

    应该像下面这样加上类名和域解析符:

    Sub obj;
    obj.BaseA::display();
    obj.BaseB::display();

    通过这个举例可以发现:在多重继承时,从不同的基类中会继承一些重复的数据。如果有多个基类,问题会更突出,所以在设计派生类时要细致考虑其数据成员,尽量减少数据冗余。

  • 相关阅读:
    h264 流、帧结构
    H264 帧结构分析、帧判断
    sigaction
    sigaction 用法实例
    sigaction函数的使用
    linux c 之signal 和sigaction区别
    linux 信号signal和sigaction理解
    Hamcrest使用
    Junit4中的新断言assertThat的使用方法
    Hamcrest Tutorial
  • 原文地址:https://www.cnblogs.com/Caden-liu8888/p/5808993.html
Copyright © 2011-2022 走看看