zoukankan      html  css  js  c++  java
  • 3.9 C++多继承

    参考:http://www.weixueyuan.net/view/6366.html

    总结:

      C++中一个派生类中允许有两个及以上的基类,我们称这种情况为多继承

      使用多继承可以描述事物之间的组合关系,但是如此一来也可能会增加命名冲突的可能性,冲突可能很有可能发生在基类与基类之间,基类与派生类之间。命名冲突是必须要解决的问题。

      为了解决命名冲突问题我们只能采用域解析操作符来区分具体所调用的类中的成员函数。

      

    在前面所有的例子中,派生类都只有一个基类,我们成这种情况为单继承。而在C++中一个派生类中允许有两个及以上的基类,我们称这种情况为多继承。单继承中派生类是对基类的特例化,例如前面中编程类书籍是书籍中的特例。而多继承中,派生类是所有基类的一种组合。

    例1:

    class teacher
    {
    public:
        void settitle(char *a){title = a;}
        char * gettitle(){return title;}
    private:
        char * title; //职称
    };
    
    class cadre
    {
    public:
        void setpost(char *a){post = a;}
        char * getpost(){return post;}
    private:
        char *post; //职务
    };
    
    class teacher_cadre: public cadre, public teacher
    {
    public:
        void setwages(int a){wages = a;}
        int getwages(){return wages;}
    private:
        int wages; //工资
    };

    在本例中我们定义了三个类,一个是教师类,该类中有一个成员变量职称title;另一个类是干部类,这个类中有一个成员变量职务post;最后定义了一个类teacher_cadre,这个类是cadre和teacher类的派生类,它也有一个新增的成员变量wages,表示工资。很明显教职工干部teacher_cadre类是cadre类和teacher类的组合。

    在多继承中,派生类继承了所有基类中的所有成员变量和成员函数,这些继承过来的成员变量及成员函数其访问规则与单继承是相同的,下面我们将例1中的teacher_cadre类中的所有成员及访问属性列于下表中。

    成员属性来源
    title 不可访问 teacher类
    settitle public teacher类
    gettitle public teacher类
    post 不可访问 cadre类
    setpost public cadre类
    getpost public cadre类
    wages private teacher_cadre类新增
    setwages public teacher_cadre类新增
    getwages public teacher_cadre类新增


    使用多继承可以描述事物之间的组合关系,但是如此一来也可能会增加命名冲突的可能性,冲突可能很有可能发生在基类与基类之间,基类与派生类之间。命名冲突是必须要解决的问题。

    例2:

    #include <iostream>
    using namespace std;
    
    class A
    {
    public:
        void setx(int a){x = a;}
        int getx(){return x;}
    private:
        int x;
    };
    
    class B
    {
    public:
        void setx(int a){x = a;}
        int getx(){return x;}
    private:
        int x;
    };
    
    class C: public A, public B
    {
    public:
        void setx(int a){x = a;}
        int getx(){return x;}
    private:
        int x;
    };
    
    int main()
    {
        C test;
        test.setx(10);
        test.B::setx(20);
        test.A::setx(30);
        return 0;
    }


    这个例子是一个非常极端的例子,只是为了说明命名冲突问题。我们来看一下例子,在本例中有三个类A、B和C,其中C类继承自类A和类B。在三个类中我们都有一个成员变量,变量名恰好都为x,然后成员函数都名为setx和getx。由于两个基类和派生类中出现了命名冲突,因此产生了遮蔽的情况。为了解决命名冲突问题我们只能采用域解析操作符来区分具体所调用的类中的成员函数。

  • 相关阅读:
    2015年北京大学软件project学科优秀大学生夏令营上机考试---C:单词翻转面试题
    跟我学Java多线程——线程池与堵塞队列
    Swift学习——类的定义,使用,继承,构造等(五)
    LNMP编译安装(centos7+nginx1.9+mysql5.6+php5.5)
    【iOS开发系列】九宫格布局
    出现异常时直接把e输出比输出e.getMessage()好得多
    往服务器上传个文件只要不到10毫秒,往数据库写条记录却要10秒
    使用struts的logic:iterate标签遍历列表时得到显示序号
    一次性上传多个文件到服务器端(一)
    Another MySQL daemon already running with the same unix socket的解决
  • 原文地址:https://www.cnblogs.com/yongpan/p/7631876.html
Copyright © 2011-2022 走看看