找回密码
 立即注册
收起左侧

C++老鸟日记021 C++访问控制及其目的或作用

5
回复
6054
查看
[复制链接]
累计签到:41 天
连续签到:1 天
来源: 原创 2018-9-14 16:45:13 显示全部楼层 |阅读模式

马上注册,查看详细内容!注册请先查看:注册须知

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
本帖最后由 baizy77 于 2018-10-1 20:53 编辑

版权声明
---------------------------------------------------------------------------------------------------------------------
该文章原创于Qter开源社区(www.qter.org
作者: 女儿叫老白 (白振勇)
转载请注明出处!
---------------------------------------------------------------------------------------------------------------------
本套课程属于:《C++跨平台开发干货》系列课程。
-----------------------------------------------------------------------------

引言:
----------------------------------------------------------------------------
       我们在前面的章节讨论过,struct的成员默认是public,class的成员默认是private。protect的成员可以被派生类访问,而无法被类对象访问。那么关于访问控制,我们还应该知道点什么呢?

正文:
----------------------------------------------------------------------------
       访问控制的目的就是为了隐藏实现。因为不是所有的成员都允许被外部访问,所以才有了访问控制。试想一下,本来是通过接口进行访问的成员变量,被派生类在任意位置修改,而该接口却一无所知是不是很不好?况且,该接口可能还要做一些额外的处理(比如,加锁,或者在该成员变量被修改后触发某个消息),这样的话,该类对象的状态可能已经超出了设计者的控制范围。因此,通过接口来访问成员变量是很必要的,对成员设置访问控制权限也同样是非常重要的。而我们在设计一个类的时候,往往想不了这么多,经常是想到啥就写啥,用到某个功能就为类写一个接口。事后才会发现,这些接口不该这样随意的暴露出去。因此,设置边界是很重要的,我们只将需要的接口开放给用户,而把细节隐藏起来。这样用户就只关心他调用的接口而无需关心内部到底发生了什么;我们也无需担心用户把手伸到我们内部来捣乱,因为有访问控制。这就好比本来我们提供了电视机遥控器,而有人偏偏想直接对电视机的电路板进行操作或处理来更换频道一样,这可不是我们设计者希望看到的。
       在多线程应用中,如果多个线程都访问同一个类对象,而该类的成员变量又是public限定符,那么当线程A修改完类的成员变量后,线程B可能马上就把它改成另一个值,这时候,线程A还不知道呢。甚至还有可能因为多线程同时修改一个变量导致应用程序崩溃。所以,还是以面向对象的思想进行编程吧,把对成员变量的访问封装在接口中,如果必要的化,加上锁进行保护。
  下面,我们对不同继承方式的访问控制做一下总结:
  1. 使用private继承,父类的protected和public属性在子类中变为private;(这样的话,用子类定义的对象就无法调用父类的任何接口,子类的成员函数无法访问父类的任何接口或成员变量。)

  2. 使用protected继承,父类的protected和public属性在子类中变为protected;(这样的话,用子类的对象也无法调用父类的接口,但是子类的成员函数可以访问父类的public和protected接口或成员变量)

  3. 使用public继承,父类中的protected和public属性不发生改变;(这样的话,用子类定义的对象可以调用父类的接口,子类的成员函数可以访问父类的public和protected接口或成员变量)
复制代码

       类的成员的访问控制总结:

  1. private:只能由1.该类中的函数、2.其友元函数访问。不能被任何其他访问,该类的对象也不能访问。

  2. protected:可以被1.该类中的函数、2.子类的函数、以及3.其友元函数访问。但不能被该类的对象访问。

  3. public:可以被1.该类中的函数、2.子类的函数、3.其友元函数访问,也可以由4.该类的对象访问。

  4.      
复制代码


   友元冲破了访问控制的限制,如果一个类A被声明为类B的友元,那么它就可以访问类B的private成员。这样做给类A开放了非常大的权限,因此我们对友元类持谨慎使用的态度。

结语:
----------------------------------------------------------------------------
       C++访问控制为面向对象编程提供了良好的语法基础,我们应充分利用。直接把类的成员变量暴露给使用者是不明智的行为,尤其在多线程应用中更是如此,使用友元时要慎之又慎。

参考资料:
----------------------------------------------------------------------------
ttps://blog.csdn.net/x_i_y_u_e/article/details/52447692
《C++编程思想》两卷合订本中文版(5.1章节),(美) Bruce Eckel  Chuck Allison著
回复

使用道具 举报

累计签到:50 天
连续签到:1 天
2018-9-21 08:01:36 显示全部楼层
baizy77 发表于 2018-9-15 21:39
区别是类对象能否访问成员变量和成员函数。其它一样。

嗯嗯                                                                        
回复 支持 反对

使用道具 举报

累计签到:41 天
连续签到:1 天
2018-9-15 21:39:52 显示全部楼层
tan 发表于 2018-9-15 11:37
使用protected继承,父类的protected和public属性在子类中变为protected;(这样的话,用子类的对象也无 ...

区别是类对象能否访问成员变量和成员函数。其它一样。
回复 支持 反对

使用道具 举报

累计签到:50 天
连续签到:1 天
2018-9-15 11:37:44 显示全部楼层
baizy77 发表于 2018-9-14 22:35
看来我没说明白。
使用private继承,父类的protected和public属性在子类中变为private;(这样的话,用子 ...

使用protected继承,父类的protected和public属性在子类中变为protected;(这样的话,用子类的对象也无法调用父类的接口,但是子类的成员函数可以访问父类的public和protected接口或成员变量)

使用public继承,父类中的protected和public属性不发生改变;(这样的话,用子类定义的对象可以调用父类的接口,子类的成员函数可以访问父类的public和protected接口或成员变量)

懂了,    应该是public 和 protected 继承主要的是:对象是不是能访问成员变量, 其他的两者都是一样的把?  
回复 支持 反对

使用道具 举报

累计签到:41 天
连续签到:1 天
2018-9-14 22:35:26 显示全部楼层
tan 发表于 2018-9-14 21:34
老师好。
   读了你的文章,    访问控制就是为了暴露不。      
  对于继承私有继承不暴露上层。

看来我没说明白。
使用private继承,父类的protected和public属性在子类中变为private;(这样的话,用子类定义的对象就无法调用父类的任何接口,子类的成员函数无法访问父类的任何接口或成员变量。)

使用protected继承,父类的protected和public属性在子类中变为protected;(这样的话,用子类的对象也无法调用父类的接口,但是子类的成员函数可以访问父类的public和protected接口或成员变量)

使用public继承,父类中的protected和public属性不发生改变;(这样的话,用子类定义的对象可以调用父类的接口,子类的成员函数可以访问父类的public和protected接口或成员变量)
回复 支持 反对

使用道具 举报

累计签到:50 天
连续签到:1 天
2018-9-14 21:34:51 显示全部楼层
本帖最后由 tan 于 2018-9-14 21:36 编辑

老师好。
   读了你的文章,    访问控制就是为了暴露不。      
  对于继承私有继承不暴露上层。
      保护继承,暴露保护和公有继承。
      公有继承, 暴露公有和保护继承。

对于一个类中有成员函数,和成员变量。    对于私有全部都隐藏了,这种是不是没有这样的继承啊?
对于单独的一个类,没有继承的情况, public 和protect 是一样的吧。 感觉没发现什么差异的,   
定义一个对象,  public 和 protect 的函数都可以访问。  继承pubic 和 proteced函数也可以访问。 成员变量也可以访问。 这protect 和 public 差异在哪?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了