C++ N问-继承问题


前言

本文介绍C++继承时一些容易出问题点


一、C++类继承问题

C++继承时一些混淆点


二、问题

  • 问题:private,protected, private 继承区别

    三种继承限制的是父类的方法在子类中的访问权限,也就是父类的成员在子类中的访问权限为min( 父类权限,继承权限)。
    继承修饰符,就像是一种筛子,将基类的成员筛到派生类。public、protected、private,就是筛子的眼。
    通过public继承,所有基类成员(除了private),public、protected都到了派生类里面,public筛眼比较大,不会改变访问权限。
    通过protected继承,所有基类成员(除了private),public、protected都到了派生类里面,protected筛眼大小适中,所有过来的成员都变成了protected。
    通过private继承,所有基类成员(除了private),public、protected都到了派生类里面,private筛眼最小,所有过来的成员都变成了private。
  1. public继承
    派生类通过public继承,基类的各种权限不变 。
    派生类的成员函数,可以访问基类的public成员、protected成员,但是无法访问基类的private成员。
    派生类的实例变量,可以访问基类的public成员,但是无法访问protected、private成员,仿佛基类的成员之间加到了派生类一般。
    可以将public继承看成派生类将基类的public,protected成员囊括到派生类,但是不包括private成员。
  2. protected继承
    派生类通过protected继承,基类的public成员在派生类中的权限变成了protected 。protected和private不变。
    派生类的成员函数,可以访问基类的public成员、protected成员,但是无法访问基类的private成员。
    派生类的实例变量,无法访问基类的任何成员,因为基类的public成员在派生类中变成了protected。
    可以将protected继承看成派生类将基类的public,protected成员囊括到派生类,全部作为派生类的protected成员,但是不包括private成员。
    private成员是基类内部的隐私,除了友元,所有人员都不得窥探。派生类的友元,都不能访问
  3. private继承
    派生类通过private继承,基类的所有成员在派生类中的权限变成了private。
    派生类的成员函数,可以访问基类的public成员、protected成员,但是无法访问基类的private成员。
    派生类的实例变量,无法访问基类的任何成员,因为基类的所有成员在派生类中变成了private。
    可以将private继承看成派生类将基类的public,protected成员囊括到派生类,全部作为派生类的private成员,但是不包括private成员。
    private成员是基类内部的隐私,除了友元,所有人员都不得窥探。派生类的友元,都不能访问

  • 问题:父类方法中访问到类中属性,在派生类中有和没有同名属性的执行区别
    代码描述为
    情况1. 子类未重载该方法
    此时无论子类有没有覆盖父类的属性,那在子类中继承到的方法均使用父类的属性
    如下:

    #include <iostream>
    #include <memory>
    using namespace std;
    
    class A {
    public:
        void printA() {
            cout << this->num << endl;
        }
    public:
        int num = 1;
    };
    
    class B : public A {
    public:
        int num = 2;
    };
    
    int main()
    {
        A a;
        B b;
        cout << "a.printA() ";
        a.printA();
        cout << "b.printA() ";
        b.printA();
        return 0;
    }
    
    a.printA() 1
    b.printA() 1
    

    情况2. 子类重载了该方法,若子类中重载了该属性,则子类重载的方法会首先访问子类中的属性,若子类没有重载该属性,则访问到的是父类中的属性,此时要保证此属性在子类中是可访问的

    class A {
    public:
        void printA() {
            cout << this->num << endl;
        }
    public:
        int num = 1;
    };
    
    class B : public A {
    public:
        void printA() {
            cout << this->num << endl;
        }
    };
    
    class C : public A {
    public:
        void printA() {
            cout << this->num << endl;
        }
    public:
        int num = 3;
    };
    
    int main()
    {
        A a;
        B b;
        C c;
        cout << "a.printA() ";
        a.printA();
        cout << "b.printA() ";
        b.printA();
        cout << "c.printA() ";
        c.printA();
        return 0;
    }
    
    a.printA() 1
    b.printA() 1
    c.printA() 3
    
  • 问题: 子类中覆盖了父类中的方法或属性,如何在子类中访问到父类中的属性或方法?
    通过前置命名空间访问,如下,强制访问A的属性

    class A {
    public:
        void printA() {
            cout << this->num << endl;
        }
    public:
        int num = 1;
    };
    
    class B : public A {
    public:
        void printA() {
            cout << this->num << endl;
        }
    };
    
    class C : public A {
    public:
        void printA() {
            cout << A::num << endl; // 强制访问A的num
        }
    public:
        int num = 3;
    };
    
    int main()
    {
        A a;
        B b;
        C c;
        cout << "a.printA() ";
        a.printA();
        cout << "b.printA() ";
        b.printA();
        cout << "c.printA() ";
        c.printA();
        return 0;
    }
    
    a.printA() 1
    b.printA() 1
    c.printA() 1
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值