• 继承复习


    近日写游戏时,发现引擎中的一个菜单不能实现自己需要的功能,所以对其扩展,继承,但有个父类中私有成员,派生类需要访问,在代码中出现一系列问题。今日复习下继承。

    一、公有(Pulic)继承

    “继承”是类的重要特性。A类继承B类,我们称B类为“基类”,也称为“父类”,A类则相应地被称为“派生类”或“子类”。A类继承了B类之后,A类就具有了B类的部分成员。那么,究竟从基类那儿得到了哪些成员,这由2方面决定,①继承方式,②基类成员的访问权限(即public/private/protected)。

    继承有三种方式,即公有(Public)继承、私有(Private)继承、保护(Protected)继承。我们先讨论最常用的公有继承。公有继承就是将基类的公有成员变为自己的公有成员,基类的保护成员变为自己的保护成员。

    #include <iostream>
    #include <string>
    using namespace std;
    
    class CBase {
        string name;
        int age;
    public:
        string getName() {
            return name;
        }
        int getAge() {
            return age;
        }
    protected:
        void setName(string s) {
            name = s;
        }
        void setAge(int i) {
            age = i;
        }
    };
    
    class CDerive : public CBase {    //用“public”指定公有继承
    public:
        void setBase(string s, int i) {
            setName(s);    //调用基类的保护成员
            setAge(i);     //调用基类的保护成员
            //调用基类的私有成员
            //cout << name <<"   " << age << endl;    //编译出错
        }
    };
    
    int main ( ) 
    {
        CDerive d;
        d.setBase("abc", 100);
        
        //调用基类的私有成员
        //cout << d.name <<"   " << d.age << endl;    //编译出错
    
        //调用基类的公有成员
        cout << d.getName() <<"   " << d.getAge() << endl;
        
        //调用基类的保护成员
        //d.setName("xyz");    //编译出错
        //d.setAge(20);        //编译出错
    
        return 0;
    }
    

    从上面的例子可以看出,对于公有继承,基类的成员能否访问,有以下特征:

    1. 基类的私有成员:在派生类和外部都不可以访问。
    2. 基类的公有成员:在派生类和外部都可以访问。
    3. 基类的保护成员:在派生类可以访问,在外部不可以访问。
    二、私有(Private)继承

    私有继承是将基类的公有成员和保护成员变成自己的私有成员,而基类的私有成员在派生类里本身就不能访问。

    #include <iostream>
    #include <string>
    using namespace std;
    
    class CBase {
        string name;
        int age;
    public:
        string getName() {
            return name;
        }
        int getAge() {
            return age;
        }
    protected:
        void setName(string s) {
            name = s;
        }
        void setAge(int i) {
            age = i;
        }
    };
    
    class CDerive : private CBase {    //用“private”指定私有继承,private可以省略
    public:
        void setBase(string s, int i) {
            setName(s);    //调用基类的保护成员
            setAge(i);     //调用基类的保护成员
            //调用基类的私有成员
            //cout << name <<"   " << age << endl;    //编译出错
        }
        string getBaseName() {
            return getName();    //调用基类的公有成员
        }
        int getBaseAge() {
            return getAge();     //调用基类的公有成员
        }
    };
    
    int main ( ) 
    {
        CDerive d;
        d.setBase("abc", 100);
        
        //调用基类的私有成员
        //cout << d.name <<"   " << d.age << endl;    //编译出错
    
        //调用基类的公有成员
        //cout << d.getName() <<"   " << d.getAge() << endl;    //编译出错
        cout << d.getBaseName() <<"   " << d.getBaseAge() << endl;
        
        //调用基类的保护成员
        //d.setName("xyz");    //编译出错
        //d.setAge(20);        //编译出错
    
        return 0;
    }
    

    从上面的例子可以看出,对于私有继承,基类的成员能否访问,有以下特征:

    1. 基类的私有成员:在派生类和外部都不可以访问。
    2. 基类的公有成员:在派生类可以访问,在外部不可以访问。
    3. 基类的保护成员:在派生类可以访问,在外部不可以访问。
    三、保护(Protected)继承

    保护继承是将基类的公有成员和保护成员变成自己的保护成员,而基类的私有成员在派生类里本身就不能访问。

    #include <iostream>
    #include <string>
    using namespace std;
    
    class CBase {
        string name;
        int age;
    public:
        string getName() {
            return name;
        }
        int getAge() {
            return age;
        }
    protected:
        void setName(string s) {
            name = s;
        }
        void setAge(int i) {
            age = i;
        }
    };
    
    class CDerive : protected CBase {    //用“private”指定私有继承
    public:
        void setBase(string s, int i) {
            setName(s);    //调用基类的保护成员
            setAge(i);     //调用基类的保护成员
            //调用基类的私有成员
            //cout << name <<"   " << age << endl;    //编译出错
        }
        string getBaseName() {
            return getName();    //调用基类的公有成员
        }
        int getBaseAge() {
            return getAge();     //调用基类的公有成员
        }
    };
    
    int main ( ) 
    {
        CDerive d;
        d.setBase("abc", 100);
        
        //调用基类的私有成员
        //cout << d.name <<"   " << d.age << endl;    //编译出错
    
        //调用基类的公有成员
        //cout << d.getName() <<"   " << d.getAge() << endl;    //编译出错
        cout << d.getBaseName() <<"   " << d.getBaseAge() << endl;
        
        //调用基类的保护成员
        //d.setName("xyz");    //编译出错
        //d.setAge(20);        //编译出错
    
        return 0;
    }
    

    从上面的例子可以看出,对于私有继承,基类的成员能否访问,有以下特征:

    1. 基类的私有成员:在派生类和外部都不可以访问。
    2. 基类的公有成员:在派生类可以访问,在外部不可以访问。
    3. 基类的保护成员:在派生类可以访问,在外部不可以访问。
    四、三种继承方式的比较

    从上面的结果来看,私有继承和保护继承作用完全一样。仔细一想其实还是有区别,区别是如果派生类再一次去派生其它类时,对于刚才的私有继承来说,再派生的类将得不到任何成员。而对于刚才的保护继承,仍能够得到基类的公有和保护成员。

     A类(基类)B类(A的派生类)C类(B的派生类)
    公有继承 公有成员 公有成员 公有成员
    私有成员 (无) (无)
    保护成员 保护成员 保护成员
    私有继承 公有成员 私有成员 (无)
    私有成员 (无) (无)
    保护成员 私有成员 (无)
    保护继承 公有成员 保护成员 保护成员
    私有成员 (无) (无)
    保护成员 保护成员 保护成员

  • 相关阅读:
    24点游戏算法
    汉诺塔算法
    台阶算法
    质因数分解算法
    全排列递归算法
    DFS 深度优先搜索例题
    容器
    数细胞
    C++栈和队列
    C++STL中vector容器 begin()与end()函数、front()与back()的用法
  • 原文地址:https://www.cnblogs.com/sharestudy/p/3195097.html
Copyright © 2020-2023  润新知