我们在上篇博客中介绍了 C++ 中的继承,那么我们想想既然是继承了,子类是否可以直接访问父类中的私有成员呢?根据面向对象理论:子类拥有父类的一切属性和行为,自然子类也就能直接访问父类的私有成员!但是根据 C++ 语法:外界不能直接访问类的 private 成员,因此子类就不能直接访问父类的私有成员!那么到底哪种是正确的呢?我们来编程实验下

#include<iostream>#include<string>usingnamespacestd;classParent{intmv;public:Parent(){mv=100;}intvalue(){returnmv;}};classChild:publicParent{public:intaddValue(intv){mv=mv+v;}};intmain(){return0;}

我们来编译下看看是否可以通过

编译报错了,说明我们的第二种分析是正确的。那么不是说继承可以获得父类的全部资源嘛,它的私有成员在子类中就不能被访问。接下来我们就要介绍一个概念了,在面向对象中的访问级别不只是 public 和 private,还有个 protected 访问级别。那么 protected 关键字的意义是什么呢?被它修饰的成员不能被外界直接访问,但是它修饰的成员可以被子类直接访问。接下来我们体验下 protected 。

#include<iostream>#include<string>usingnamespacestd;classParent{protected:intmv;public:Parent(){mv=100;}intvalue(){returnmv;}};classChild:publicParent{public:intaddValue(intv){mv=mv+v;}};intmain(){Parentp;cout<<"p.mv="<<p.value()<<endl;Childc;cout<<"c.mv="<<c.value()<<endl;c.addValue(50);cout<<"c.mv="<<c.value()<<endl;return0;}

我们来试下将 private 属性换成 protected,看看编译可以通过吗?

我们看到编译通过了,也正常运行了。那么我们在 main 函数中直接给 p.mv 和 c.mv 赋值为 1000 呢?我们看看编译结果

我们看到编译失败了,因为成员变量 mv 是 protected 的,所以在外界不能直接访问。那么为什么在面向对象中需要 protected 呢?我们来想想现实生活中,比如小明要去医院看病。有些隐秘的病史,小明肯定不想让别人知道,但是这时必须得给医生坦白,不然没法治病哈。这时便有了 protected 这个需求了,这个病史不是纯私有的,但又不是暴露在大众之下的。我们面向对象的思想中,为了更完美的贴合生活,便有了 protected 这个关键字。那么我们在定义类时访问级别是怎样选择的呢?我们来看看下面这张表。注:表是由唐长老总结出来的!

关系已经很明确了,我就不多废话了。下来我们来看个示例,关系如下

用程序描述出来就是下面这

#include<iostream>#include<string>#include<sstream>usingnamespacestd;classObject{protected:stringmName;stringmInfo;public:Object(){mName="Object";mInfo="";}stringname(){returnmName;}stringinfo(){returnmInfo;}};classPoint:publicObject{private:intmX;intmY;public:Point(intx=0,inty=0){ostringstreams;mX=x;mY=y;mName="Point";s<<"P("<<mX<<","<<mY<<")";mInfo=s.str();}intx(){returnmX;}inty(){returnmY;}};classLine:publicObject{private:PointmP1;PointmP2;public:Line(Pointp1,Pointp2){ostringstreams;mP1=p1;mP2=p2;mName="Line";s<<"Lineform"<<mP1.info()<<"to"<<mP2.info()<<"!";mInfo=s.str();}Pointbegin(){returnmP1;}Pointend(){returnmP2;}};intmain(){Objecto;Pointp(1,2);Pointpn(5,6);Linel(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;return0;}

我们看看编译结果


我们看到在 Object 类中没有相应的描述,所以它的信息为空,别的打印是正确的。通过对继承中的访问级别的学习,总结如下:1、面向对象中的访问级别不只是 public 和 private;2、protected 修饰的成员不能被外界访问,它使得子类能够访问父类的成员;3、protected 关键字是为了继承而专门设计的;4、没有 protected 就无法完成真正意义上的代码复用。


欢迎大家一起来学习 C++ 语言,可以加我QQ:243343083。