你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

c++——类的继承中的访问级别的学习

[复制链接]
gaosmile 发布时间:2020-8-19 16:19
上一篇文章我们介绍了c++中类的继承学习总结;今天我们继续来分享c++中类的继承中的访问级别的学习总结。
一、继承中的访问级别学习:
1、子类是否可以直接访问父类的私用成员吗?
从面向对象理论角度来看:
  • 子类拥有父类的一切属性和行为,也就是说,子类能够直接访问父类的私有成员。

从c++的语法角度看:
  • 外界不能直接访问类的private成员,也就是说,子类不能直接访问父类的私用成员。

代码示例:
#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;
}
输出结果:
root@txp-virtual-machine:/home/txp# g++ test.cpp
test.cpp: In member function ‘int Child::addValue(int)’:
test.cpp:9:9: error: ‘int Parent::mv’ is private
     int mv;
         ^
test.cpp:27:9: error: within this context
         mv = mv + v;    //  如何访问父类的非公有成员
         ^
test.cpp:9:9: error: ‘int Parent::mv’ is private
     int mv;
         ^
test.cpp:27:14: error: within this context
         mv = mv + v;    //  如何访问父类的非公有成员
              ^

注解:我们可以看到子类不能直接访问到父类里面的属性
2、继承中的访问级别关系
  • 面向对象中的访问级别不只是public和private
  • 可以定义protected访问级别
  • 关键字protect的意义
        --修饰的成员不能被外界直接访问

            -- 修饰的成员可以被子类直接访问
代码实现
#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;
}
运行结果:
root@txp-virtual-machine:/home/txp# g++ test.cpp
test.cpp: In function ‘int main()’:
test.cpp:9:9: error: ‘int Parent::mv’ is protected
     int mv;
         ^
test.cpp:37:8: error: within this context
      p.mv = 1000;    // error
        ^
test.cpp:9:9: error: ‘int Parent::mv’ is protected
     int mv;
         ^
test.cpp:47:7: error: within this context
     c.mv = 10000;  // error

注解:这里我们把父类的属性private修改成protect,这里我们注意到在子类里面的方法中是可以使用父类中的属性mv了,只不过在int main()函数中,使用父类和子类定义的对象,均不可以对父类中的属性mv进行访问,这一点要注意。
3、为什么面向对象中需要protect?
我们还是用生活中的例子来理解,每个人的个人隐私,是不能泄露的,也就是我们c++中的private关键字;而你身上穿的衣服,每个人都可以知道,也就是c++中的public关键字;最后我们的protect关键字,为啥c++中会需要它,我想还是跟生活中有关(所以说,面向对象的编程,非常贴近生活),比如说,家庭开会,有些事情就不能让外人知道,但是自己家人就可以知道,所以这跟protect关键字的用法非常像,也就是说,protect关键鉴于private和public之间。
4、定义类时访问级别的选择:
微信图片_20200819161828.png
注解:从图中我们可以发现,当有发生继承关系时,就考虑使用protect关键字
5、组合和继承的综合运用
微信图片_20200819161831.png
说明:Object这个类是被用来继承的;Line和Point两个类进行组合。
代码示例:
#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;
}
输出结果:
root@txp-virtual-machine:/home/txp# ./a.out
Object


Point
P(1, 2)

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

二、总结:
  • 面向对象中的访问级别不只是public和private
  • protected修饰的成员不能别外界所访问
  • protected使得子类能够访问父类的成员
  • protected关键字为了继承而专门设计的
  • 没有protected关键字就无法完成真正代码意义上的代码复用了


好了,今天的分享就到这里,如果文章中有错误或者不理解的地方,可以交流互动,一起进步。

收藏 评论0 发布时间:2020-8-19 16:19

举报

0个回答

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版