• 类的继承C++


    类的继承

    成员权限问题:

    public公有级别能被外界直接访问,**private只能被在类内部和类成员函数访问,**不能被外界直接访问。子类继承父类后,便拥有了父类的所有属性,

    //单继承问题,继承不会扩大成员权限,只会保持不变或者变小

    1-私有属性的继承

    
    #include
    using namespace std;
    class A
    {
    private:
    int m_a=4;
    
    public:
    void print(){
        cout<<"m_a:"<<m_a<<endl;
    };
    };
    class B:public A
    {
        private:
        int m_b;
    
    };
    
    int main()
    {
        B b;
    
        b.print();
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    1-类A中的所有数据成员都会被类B继承(也就是类B有一份类A的拷贝本),尽管类A中的m_a是私有属性,但类B中依旧会有一份(只是无法直接访问)。
    2-子类继承的私有属性无法直接访问,但可以间接通过调用父类的get方法访问

    2-保护属性的继承

    #include 
    #include 
     
    using namespace std;
     
    class Parent
    {
    protected:	//将原来的private属性改为protect属性
        int m_value1;
        void fun1()
        {
        	cout << "Parent::fun1()" << endl;
        }
     
    public:
        int m_value2;
        void fun2()
        {
        	cout << "Parent::fun2()" << endl;
        }
    };
     
    class Child : public Parent	
    {
    public:
        void ChildFun()
        {
        	m_value1 = 10;	//子类中直接访问父类的保护成员变量
        	fun1();			//子类中直接访问父类的保护成员函数
     
        	m_value2 = 20;	//子类中直接访问父类的公有成员变量
        	fun2();			//子类中直接访问父类的公有成员变量
        }
     
    };
     
    int main()
    {
        Child C;
        C.ChildFun();
    	
        system("pause");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    -protect修饰的成员不能被外界所访问 protect修饰的成员能被子类直接访问

    //多继承出现的同名函数问题()

    如果某派生类的多个基类拥有同名的成员,同时,派生类又新增这样的同名成员,在这种情况下,派生类成员将因此拥有所有基类的同名成员。使用“对象名.成员名”或“对象指针名->成员名”方式可以唯一标识和访问派生类新增成员,基类的同名成员也可以使用基类名或作用域分辨符访问。

    样例一 这里只演示了继承一个父类的情况(继承多个父类的情况将在多态那里介绍)

    // 多继承同名函数问题(多态问题)    
    
    #include 
    using namespace std;
    class BaseClass
    {
    public:
        //  virtual	void fn1() {
        // 		cout << "调用BaseClass的成员函数fn1aa" << endl;
        // 	}
        //  virtual	void fn2() {
        // 		cout << "调用BaseClass的成员函数fn2bb" << endl;
        // 	}
        void fn1()
        {
            cout << "调用BaseClass的成员函数fn1aa" << endl;
        }
        void fn2()
        {
            cout << "调用BaseClass的成员函数fn2bb" << endl;
        }
    };
    class DerivedClass : public BaseClass
    {
    public:
        void fn1()
        {
            cout << "调用DerivedClass的成员函数fn1cc" << endl;
        }
        void fn2()
        {
            cout << "调用DerivedClass的成员函数fn2dd" << endl;
        }
    };
    int main()
    {
        // 1-通过类名限定
        DerivedClass p1;
        p1.BaseClass::fn1();
        p1.BaseClass::fn2();
        p1.DerivedClass::fn1();
        p1.DerivedClass::fn2();
        cout << "********************" << endl;
        // 2-通过创建对象
        // a-正常指针
        DerivedClass *ptr = new DerivedClass; //本质是调用构造函数
        ptr->fn1();
        ptr->fn2();
        BaseClass *pptr = new BaseClass;
        pptr->fn1();
        pptr->fn2();
        cout << "*****************" << endl;
    
        // b-父类指针指向子类对象
        //若基类的函数没加virtual 则看指针类型
        //若基类的函数加了virtual 则看调用对象
        BaseClass *Bptr = new DerivedClass;
        Bptr->fn1();
        Bptr->fn2();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    继承时考虑的构造函数

    #include 
    using namespace std;
    
    class father
    {
        int age;
    
    public:
        int height;
    
        father(int age = 0, int height = 0);
        void print();
    };
    father::father(int age, int height) : age(age), height(height){};
    void father::print()
    {
        cout << "height: " << this->height << "\t"
             << "age: " << this->age << endl;
    };
    class son : public father
    {
    public:
    
        son(int s_age, int s_height) : father(s_age ,s_height)
        {
    print();
       
        };
    };
    
    int main()
    {
        son s(11, 22);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    1-父类数据成员的初始化一定依赖父类的构造函数;

    3-先调用父类的构造函数,再调用子类的构造函数

    2-子类的构造函数一定需要调用父类的构造函数;(如果没有显式调用,那父类的构造函数一定是默认的无参构造函数)

    关于上面的第二点:如下:

    #include 
    using namespace std;
    class father
    {
        int age;
    
    public:
        int height;
        father()
        {
            cout << "调用父类的构造函数aa" << endl;
        };
    };
    
    class son : public father
    {
    private:
        int age;
    
    public:
        son(int age)
        {
            this->age = age;
            cout<<this->age<<endl;
        };
    
        // son() :father()// 其实就是隐式调用父类构造,也可以写成显式调用。
        // {
    
        // };
    };
    
    int main()
    {
        son s(11);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    关于在写构造函数出现的问题

    //继承的时候出现的问题
    #include 
    using namespace std;
    
    class father
    {
        int age;
    
    public:
        int height;
    
        father(int age = 0, int height = 0);
        void print();
    };
    father::father(int age, int height) : age(age), height(height){};
    void father::print()
    {
        cout << "height: " << this->height << "\t"
             << "age: " << this->age << endl;
    };
    class son : public father
    {
    public:
        son(int s_age, int s_height) : father(s_age), height(s_height){
            
            print();
            
        };
      
    };
    
    int main()
    {
        son s(11, 22);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    报错:class ‘son’ does not have any field named ‘height’

    原因: 子类的参数初始化列表只能初始化自己的东西; 要初始化父类继承过来的东西,只能传给父类的构造函数,在父类的构造函数里初始化。 或者在子类构造函数体内初始化。

    所以将子类的构造函数改为:

      son(int s_age, int s_height) : father(s_age),{
            height= s_height;
            print();
            
        };
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    2>&1到底是什么意思?
    工作10年,浅谈经历过的高并发架构设计实战经验
    应用集成-在Hexo、Hugo博客框架中使用Gitalk基于Github上仓库项目的issue无后端服务评论系统实践
    如何通用系统平台这个黑科技把网店做大,需要注意什么?
    APISpace 汉语拆字API
    学生网页课程设计期末作业 HTML+CSS+JavaScript甜品蛋糕网页设计(5页)
    计算机毕业设计springboot+vue基本微信小程序的乐旋乒乓球课程管理系统 uniapp 小程序
    基于PHP+MySQL游戏视频网站的设计与实现
    高可用篇_A Docker容器化技术_I Docker基本概念
    微信小程序遮罩层悬浮窗踩坑
  • 原文地址:https://blog.csdn.net/qq_55125921/article/details/126076903