• C++语言解读三


    今天说说继承.在C++中继承分共有继承,私有继承,多继承和单一继承,这点和C#不同,另外vritual关键字的用法也不相同,下面一一讲解

    1:公有单一继承

    #include<iostream>
    using namespace std;
    //公有单一继承 例子
    class A
    {
    public:
        void print1()const{cout<<"父类方法"<<endl;}
    };
    class B:public A
    {
    public:
        void Print2()const{cout<<"子类方法"<<endl;}
    };
    int main()
    {
        B b;//栈中创建对象
        b.print1();//父类方法
        b.Print2();//自己的方法
        return 0;
    }
    /*
       程序说明
         子类在公有继承父类后,父类的公有方法在子类中依然是公有方法
    */

    2:公有多继承

    #include<iostream>
    using namespace std;
    //公有多继承例子
    class A
    {
    public:
        void print1()const{cout<<"A类方法"<<endl;}
    };
    class B
    {
    public:
        void Print2()const{cout<<"B类方法"<<endl;}
    };
    class C:public A,public B
    {
    public:
        void Print3()const{cout<<"C类方法"<<endl;}
    };
    int main()
    {
        C c;
        c.print1();//A方法
        c.Print2();//B方法
        c.Print3();//C方法
        return 0;
    }

    3:多继承(有公有和私有一起)

    #include<iostream>
    using namespace std;
    //多继承(有公有和私有一起)
    class A
    {
    public:
        void print1()const{cout<<"A类方法"<<endl;}
    };
    class B
    {
    public:
        void Print2()const{cout<<"B类方法"<<endl;}
    };
    class C:public A,private B
    {
    public:
        void Print3()const{cout<<"C类方法"<<endl;}
        void Print4(){Print2();}
    };
    int main()
    {
        C c;
        c.print1();//A方法
        
    //c.Print2();//这里调用B类方法不能运行
        c.Print3();//C方法
        c.Print4();//这里调用B类方法
        return 0;
    }
    /*
       程序说明

         1:私有继承用private关键字
         2:私有继承有父类的公有方法在子类里就变成私有方法
         3私有继承有父类的私有方法在子类里就变成不可访问
         如需方法,就在子类里添加公有接口方法(就像程序里的Print4()方法一样来调用)
    */

    4单一继承中的构造函数执行顺序

     #include<iostream>
    using namespace std;
    //单一继承中的构造函数执行顺序
    class A
    {
    public:
        A(){cout<<"父类构造函数执行"<<endl;}
    };
    class B:public A
    {
    public:
        B(){cout<<"子类构造函数执行"<<endl;}
    };
    int main()
    {
        B b;
        return 0;
    }
    /*
        程序说明

         在创建子类后先构造它的父类的构造函数,然后在构造自己
    */

    5多继承中的构造函数执行顺序

    #include<iostream>
    using namespace std;
    //多继承中的构造函数执行顺序
    class A
    {
    public:
        A(){cout<<"A类构造函数执行"<<endl;}
    };
    class B
    {
    public:
        B(){cout<<"B类构造函数执行"<<endl;}
    };
    class C
    {
    public:
        C(){cout<<"C类构造函数执行"<<endl;}
    };
    class D:public A,public B,public C
    {
    public:
       D(){cout<<"D类构造函数执行"<<endl;}
    };
    int main()
    {
        D d;
        return 0;
    }
    /*
        程序说明

         在多继承中构造函数的执行顺序为第一个继承的先构造
         这里将会先构造A,然后B,最后C
    */

    6继承中的析购函数执行顺序

    #include<iostream>
    using namespace std;
    //继承中的析购函数执行顺序
    class A
    {
    public:
        A(){cout<<"A类构造函数执行"<<endl;}
        ~A(){cout<<"A类析购函数执行"<<endl;}
    };
    class B
    {
    public:
        B(){cout<<"B类构造函数执行"<<endl;}
        ~B(){cout<<"B类析购函数执行"<<endl;}
    };
    class C
    {
    public:
        C(){cout<<"C类构造函数执行"<<endl;}
        ~C(){cout<<"C类析购函数执行"<<endl;}
    };
    class D:public A,public B,public C
    {
    public:
       D(){cout<<"D类构造函数执行"<<endl;}
       ~D(){cout<<"D类析购函数执行"<<endl;}
    };
    int main()
    {
        D d;
        return 0;
    }
    /*
        程序说明

         在多继承中析购函数的执行顺序为先析购子类,然后一级一级的析购下去
    */

    7:多继承中出现的两义性,什么是两义性呢?请看代码

    #include<iostream>
    using namespace std;
    class A
    {
    public:
        void Print(){cout<<"类A方法"<<endl;}
    };
    class B:virtual public A
    {
    };
    class C:virtual public A
    {
    };
    class D:public B,public C
    {

    };
    int main()
    {
        D d;
        //d.Print();这里会出现ambiguous错误。
        
    //编译器会提示这个Print是从类A继承的还是从类B继承的,它不明白
        
    //下面是正确的调用
        d.C::Print();//用类名加双冒号调用
        return 0;
    }
    /*
        程序说明

         
    */

    8:虚基类是不会产生两义性这个问题呢,那么怎么定义虚基类呢?请看代码

    #include<iostream>
    using namespace std;
    //两义性
    class A
    {
    public:
        void Print(){cout<<"类A方法"<<endl;}
    };
    class B:virtual public A
    {
    };
    class C:virtual public A
    {
    };
    class D:public B,public C
    {

    };
    int main()
    {
        D d;
        d.Print();
        return 0;
    }
    /*
        程序说明

         用virtual关键字定义虚基类
    */

    9:virtual关键字的使用

    #include<iostream>
    using namespace std;
    //虚函数
    class A
    {
    public:
        virtual void Print(){cout<<"类A方法"<<endl;}
    };
    class B:virtual public A
    {
    public:
        void Print(){cout<<"类B方法"<<endl;} 
    };
    int main()
    {
        //定义指向类A指针
        
    //指针多态
        A* p=new A;
        p->Print();//这里将访问类A方法
        p=new B;
        p->Print();//这里将会访问类B方法
        
    //=-==============
        
    //可能有些使用C#的程序员觉得这是必然的。
        
    //这里如果我们不用指针,而转用对象,看看是什么情况
        A a;
        B b;
        a.Print();
        a=b;//注意这里将类B的一个对象赋予给类A的一个对象,再次调用a.Print()方法看看
        a.Print();//这里还是会访问类A方法
        return 0;
    }
    /*
        程序说明

          在动态联编情况下。如果程序实现多态必须用指针或引用,用对象是不可以的
    */

    最后写一个小的程序来最终说明虚函数的使用

    #include<iostream>
    using namespace std;
    class Language
    {
    public:
        virtual void Print()
            const
        {
           cout<<"程序默认使用语言为Java"<<endl;
        }
    };
    class Cshop:public Language
    {
        void Print()
            const
        {
           cout<<"程序使用C#语言编写"<<endl;
        }
    };
    class Cpp:public Language
    {
        void Print()
            const
        {
           cout<<"程序使用C++语言编写"<<endl;
        }
    };
    class Dephi:public Language
    {
        void Print()
            const
        {
           cout<<"程序使用Dephi语言编写"<<endl;
        }
    };
    int main()
    {
        //定义个基类指针
        Language* p;
        Language* p1;
        int con;
        bool bl=true;//退出循环使用
        while(true)
        {
            cout<<"<1>Cshop <2>Cpp <3>Dephi <0>quit";
            cin>>con;
            switch(con)
            {
            case 1:
                p=new Cshop;
                break;
            case 2:
                p=new Cpp;
                break;
            case 3:
                p=new Dephi;
                break;
            case 0:
                bl=false;
                break;
            default:
                p=new Language;
                break;
            }
            if(!bl){
                //输入0情况下退出循环
                break;
            }
            p1=p;
            p1->Print();
        }
        return 0;
    }
  • 相关阅读:
    es 6.7.2
    nginx https
    es 遍历
    bloomfilter
    CentOS8安装JDK1.8
    vmware快速搭建k8s集群 (vmware16|centos8|docker19.03.15|k8s1.16.9|calico3.16)(kubeadm安装方式)
    Nmap扫描结果转换xml>html
    SpringBoot 分环境打包
    JetBrains 里不为人知的秘密(16)CLion 修改for 模板最新(20220519) 大飞
    elementui 之upload 文件上传
  • 原文地址:https://www.cnblogs.com/xuting/p/c__.html
Copyright © 2020-2023  润新知