zoukankan      html  css  js  c++  java
  • 【C++课程学习10】继承

    参考

    • 范磊C++(第12课时)

    笔记

    继承和派生的基本概念

    • 什么是继承和派生

    在这里插入图片描述

    在这里插入图片描述

    • 复杂的继承和派生

    在这里插入图片描述

    • 继承和派生如何在C++中实现?
      在这里插入图片描述

    在这里插入图片描述

    派生类型(派生权限)的概念,以后会讲到。

    单一继承

    只有一个基类

    #include <iostream>
    using namespace std;
    class Father
    {
    private:
        int fatherHight,fatherWeight;
    public://构造函数只有一个参数,与下面的对应!
        void setFatherHight(int x){fatherHight=x;}
        void setFatherWeight(int x){fatherWeight=x;}
        void getFatherHightAndWeight(){cout<<"身高为"<<fatherHight<<endl;
            cout<<"体重为"<<fatherWeight<<endl;}
    
    };
    
    class Son :public Father
    {
    private:
        int sonWidth,sonLong;
    public:
        void setSonHWidth(int x){sonWidth=x;}
        void setSonWLong(int x){sonLong=x;}
        void getsonHightAndWeight(){cout<<"肩宽为"<<sonWidth<<endl;
            cout<<"臂长为"<<sonLong<<endl;}
    
    
    };
    
    int main(int argc, const char * argv[]) {
        Son LiMing;
        LiMing.setFatherHight(180);
        LiMing.setFatherWeight(80);
        LiMing.setSonWLong(134);
        LiMing.setSonHWidth(65);
        LiMing.getsonHightAndWeight();
        LiMing.getFatherHightAndWeight();
        return 0;
    }
    

    输出结果:

    在这里插入图片描述

    保护成员

    在这里插入图片描述

    #include <iostream>
    using namespace std;
    class Father
    {
    //private://子类不能访问
    protected://只能子类来访问
        int fatherHight,fatherWeight;
    public://构造函数只有一个参数,与下面的对应!
        void setFatherHight(int x){fatherHight=x;}
        void setFatherWeight(int x){fatherWeight=x;}
        //void getFatherHightAndWeight(){cout<<"身高为"<<fatherHight<<endl;
          //  cout<<"体重为"<<fatherWeight<<endl;}
    
    };
    
    class Son :public Father
    {
    private:
        int sonWidth,sonLong;
    public:
        void setSonHWidth(int x){sonWidth=x;}
        void setSonWLong(int x){sonLong=x;}
        //void getsonHightAndWeight(){cout<<"肩宽为"<<sonWidth<<endl;
          //  cout<<"臂长为"<<sonLong<<endl;}
        void PrintAll(){
            cout<<"肩宽为"<<sonWidth<<endl;
            cout<<"臂长为"<<sonLong<<endl;
            cout<<"身高为"<<fatherHight<<endl;
            cout<<"体重为"<<fatherWeight<<endl;
        }
    
    
    };
    
    int main(int argc, const char * argv[]) {
        Son LiMing;
        LiMing.setFatherHight(180);
        LiMing.setFatherWeight(80);
        LiMing.setSonWLong(134);
        LiMing.setSonHWidth(65);
        //LiMing.getsonHightAndWeight();
        //LiMing.getFatherHightAndWeight();
        LiMing.PrintAll();
        return 0;
    }
    

    输出结果:
    在这里插入图片描述

    共有派生

    • 共有
      在这里插入图片描述

    • 保护
      在这里插入图片描述

    • 私有
      在这里插入图片描述

    继承的赋值

    在这里插入图片描述

    子类可以赋值给父类,但父类不能给子类。
    因为父类的成员数少。
    同样,基类的指针可以指向派生类对象,但是派生类指针不能指向基类对象。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    私有派生(继承)

    在这里插入图片描述

    #include <iostream>
    using namespace std;
    class Father
    {
    public:
        void room(){cout<<"父亲的大房子我可以享受"<<endl;}
    };//注意分号
    
    class Son: private Father
    {
    public:
        void enjoy(){room();}
    };
    
    int main(int argc, const char * argv[]) {
        Son a;
        a.enjoy();
        return 0;
    }
    

    输出结果:

    在这里插入图片描述

    在这里插入图片描述

    多重继承

    在这里插入图片描述

    #include <iostream>
    using namespace std;
    class Father
    {
    public:
        void setA(int a ){tall=a;}
        void print1(){cout<<"身高的值:"<<tall<<endl;}
    private:
        int tall;
    };
    
    class Mother
    {
    public:
        void setB(int a ){weight=a;}
        void print2(){cout<<"体重的值:"<<weight<<endl;}//成员函数名字最好不要相同,否则会报错!
    private:
        int weight;
    };
    
    class Son: public Father,public Mother
    {
    public:
        void setC(int a ){age=a;}
        void print3(){print1();print2();cout<<"年龄的值:"<<age<<endl;}
    private:
        int age;
    };
    
    int main(int argc, const char * argv[]) {
        Son Mike;
        Mike.setA(175);
        Mike.setB(80);
        Mike.setC(25);
        Mike.print3();
        return 0;
    }
    

    输出:

    在这里插入图片描述

    当然同样的也可以设置派生权限。

    继承的构造与构析

    构造函数和析构函数的执行顺序。
    在这里插入图片描述

    在这里插入图片描述

    基类的构造顺序是按继承时的给定顺序执行。
    析构时则正好相反。
    在这里插入图片描述

    向基类构造函数传递参数

    在这里插入图片描述

    在这里插入图片描述

    • 方法1
      方法正确,但是调用父类的构造函数对创建子类对象没有帮助,( 无用的构造函数)这相当于浪费了系统的开销。
    #include <iostream>
    #include<string>
    using namespace std;
    class Father
    {
    public:
        Father(){cout<<"构造基类对象"<<endl;}
        ~Father(){cout<<"析构基类对象"<<endl;}
        void setA(int a ){tall=a;}
        void print(){cout<<name<<"身高的值:"<<tall<<"cm"<<endl;}
    protected:
        string name;
        int tall;
    private:
    
    };
    
    class Son :public Father
    {
    public:
        Son(string a, int i, int j){
            name=a;
            tall=i;
            weight=j;
            cout<<"构造子类对象"<<endl;}
        ~Son(){cout<<"析构子类对象"<<endl;}
        void setA(int a ){tall=a;}
        void print1(){print();cout<<"体重的值:"<<weight<<"kg"<<endl;}//不能覆盖掉父类的,因此要改名。
    protected:
        int weight;
    private:
    };
    
    int main(int argc, const char * argv[]) {
        Son Mike("Mike",180,80);
        Mike.print1();
        cout<<"程序结束"<<endl;
        return 0;
    }
    

    输出:
    在这里插入图片描述

    • 方法2
      充分利用基类的构造函数。
    #include <iostream>
    #include<string>
    using namespace std;
    class Father
    {
    public:
        //Father(){cout<<"构造基类对象"<<endl;}
        Father(string a, int i){
            name=a;
            tall=i;
            cout<<"构造带两个参数的基类对象"<<endl;}
        ~Father(){cout<<"析构基类对象"<<endl;}
        void setA(int a ){tall=a;}
        void print(){cout<<name<<"身高的值:"<<tall<<"cm"<<endl;}
    protected:
        string name;
        int tall;
    private:
    
    };
    
    class Son :public Father
    {
    public:
        Son(string a, int i, int j):Father(a,i){
            weight=j;
            cout<<"构造子类对象"<<endl;}
        ~Son(){cout<<"析构子类对象"<<endl;}
        void setA(int a ){tall=a;}
        void print1(){print();cout<<"体重的值:"<<weight<<"kg"<<endl;}//不能覆盖掉父类的,因此要改名。
    protected:
        int weight;
    private:
    };
    
    int main(int argc, const char * argv[]) {
        Son Mike("Mike",180,80);//
        Mike.print1();
        cout<<"程序结束"<<endl;
        return 0;
    }
    
    

    输出:

    在这里插入图片描述

    在这里插入图片描述

    多重继承容易产生两义性

    成员重名导致的问题。
    会产生警告⚠️
    强行运行的话,就会产生覆盖问题。
    可以使用作用域操作符来避免这个问题。

    两义性的归属问题

    在这里插入图片描述

    继承中的重载

    在这里插入图片描述

    一旦子类定义了构造函数,基类中的构造函数就会被覆盖。
    【问题】const函数,只能由const对象调用吗???

  • 相关阅读:
    伪多项式时间 Pseudo-polynomial time
    Aho-Corasick算法
    写给十八岁以下的你
    网络流算法
    Java static关键字
    带有负权边的最短路径问题
    Miller_Rabin(米勒拉宾)素数测试
    关于同余与模运算的总结
    UVa1585
    UVa修改版02
  • 原文地址:https://www.cnblogs.com/vrijheid/p/14223012.html
Copyright © 2011-2022 走看看