【C++深度剖析教程23】继承中的访问级别

本C++课程学习记录,完全来源于狄泰软件学院的相关课程,想一起学习的加我q1126137994或者q群199546072
给你推荐更多相关课程。

今天学习C++中继承的访问级别。首先我们思考一个问题,子类是否可以直接访问父类的私有成员???
我们可以看看下图的思考过程:
这里写图片描述
可以看出,两者互相矛盾,那么实际上是什么样呢?我们只有让编译器告诉我们了:
看下面的程序:

#include <iostream>
#include <string>

using namespace std;

class Parent
{
private:
    int mv;
public:
    Parent()
    {
        mv = 100;
    }

    int value()
    {
        return mv;
    }
};

class Child : public Parent
{
public:
    int addValue(int v)
    {
        mv = mv + v;    // ???? 如何访问父类的非公有成员
    }
};

int main()
{   
    return 0;
}

编译显示有错误:
这里写图片描述
由结果显示知:我们的子类不能访问父类的私有成员!!!但是我们上一篇文章也说了,我们的子类是需要继承父类所有的属性与行为的。

所以在C++中,类中还定义了一种访问级别protected,被protected修饰的成员可以被子类访问,而不能被其他类访问。

  • 面向对象中的访问级别不只是private和public
  • 可以定义protected的访问级别
  • protected修饰的成员不能被外界直接访问
  • protected修饰的成员可以被子类直接访问

下面我们看一个例子来理解protected的访问级别:

#include <iostream>
#include <string>

using namespace std;

class Parent
{
protected:
    int mv;
public:
    Parent()
    {
        mv = 100;
    }

    int value()
    {
        return mv;
    }
};

class Child : public Parent
{
public:
    int addValue(int v)
    {
        mv = mv + v;    
    }
};

int main()
{   
    Parent p;

    cout << "p.mv = " << p.value() << endl;

    // p.mv = 1000;    // error

    Child c;

    cout << "c.mv = " << c.value() << endl;

    c.addValue(50);

    cout << "c.mv = " << c.value() << endl;

    // c.mv = 10000;  // error

    return 0;
}

运行结果为:
p.mv = 100
c.mv = 100
c.mv = 150

由运行结果,以及代码的分析,知protected修饰的成员可以被子类访问。

由此我们可以得出一个对于定义类时的一个访问级别的的选择的流程框图:
这里写图片描述

最后我们做一个综合性的联系,结合类的组合与类的继承,完成下图的程序
这里写图片描述
上图是实现实体,直线,点,这三个类的组合关系,与继承关系,代码如下:

#include <iostream>
#include <string>
#include <sstream>

using namespace std;

class Object
{
protected:
    string mName;
    string mInfo;
public:
    Object()
    {
        mName = "Object";
        mInfo = "";
    }
    string name()
    {
        return mName;
    }
    string info()
    {
        return mInfo;
    }
};

class Point : public Object
{
private:
    int mX;
    int mY;
public:
    Point(int x = 0, int y = 0)
    {
        ostringstream s;

        mX = x;
        mY = y;
        mName = "Point";

        s << "P(" << mX << ", " << mY << ")";

        mInfo = s.str();
    }
    int x()
    {
        return mX;
    }
    int y()
    {
        return mY;
    }
};

class Line : public Object
{
private:
    Point mP1;
    Point mP2;
public:
    Line(Point p1, Point p2)
    {
        ostringstream s;

        mP1 = p1;
        mP2 = p2;
        mName = "Line";

        s << "Line from " << mP1.info() << " to " << mP2.info();

        mInfo = s.str();
    }
    Point begin()
    {
        return mP1;
    }
    Point end()
    {
        return mP2;
    }
};

int main()
{   
    Object o;
    Point p(1, 2);
    Point pn(5, 6);
    Line l(p, pn);

    cout << o.name() << endl;
    cout << o.info() << endl;

    cout << endl;

    cout << p.name() << endl;
    cout << p.info() << endl;

    cout << endl;

    cout << l.name() << endl;
    cout << l.info() << endl;

    return 0;
}

运行结果为:
Object

Point
P(1, 2)

Line
Line from P(1, 2) to P(5, 6)

由以上的程序分析总结:

  • protected修饰的成员不能被外界所访问
  • protected修饰的成员使得子类可以访问父类的成员
  • protected是专门为继承而专门设计的
  • 没有protected就无法完成真正意义上的代码复用

想一起探讨以及获得各种学习资源加我(有我博客中写的代码的原稿):
qq:1126137994
微信:liu1126137994
可以共同交流关于嵌入式,操作系统,C++语言,C语言,数据结构等技术问题。

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页