找回密码
 立即注册

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

发表于 7 天前 | 显示全部楼层 |阅读模式
本帖最后由 baizy77 于 2018-9-14 22:33 编辑

微信公众号: 星点课堂
新浪微博:女儿叫老白
网易云课堂:女儿叫老白
网易云课堂免费课程:《C++跨平台开发中的编译错误》
网易云课堂免费课程:《C++老鸟日记》
----------------------------------------------------------------------------
(5.1)
引言:
----------------------------------------------------------------------------
       我们在前面的章节讨论过,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

回复

使用道具 举报

发表于 7 天前 | 显示全部楼层
本帖最后由 tan 于 2018-9-14 21:36 编辑

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

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

使用道具 举报

 楼主| 发表于 7 天前 | 显示全部楼层
tan 发表于 2018-9-14 21:34
老师好。
   读了你的文章,    访问控制就是为了暴露不。      
  对于继承私有继承不暴露上层。

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

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

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

使用道具 举报

发表于 6 天前 | 显示全部楼层
baizy77 发表于 2018-9-14 22:35
看来我没说明白。
使用private继承,父类的protected和public属性在子类中变为private;(这样的话,用子 ...

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

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

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

使用道具 举报

 楼主| 发表于 6 天前 | 显示全部楼层
tan 发表于 2018-9-15 11:37
使用protected继承,父类的protected和public属性在子类中变为protected;(这样的话,用子类的对象也无 ...

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

使用道具 举报

发表于 14 小时前 | 显示全部楼层
baizy77 发表于 2018-9-15 21:39
区别是类对象能否访问成员变量和成员函数。其它一样。

嗯嗯                                                                        
回复 支持 反对

使用道具 举报

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

本版积分规则

baizy77

    主题

    帖子

    60

    积分

    Qter1级会员

    Rank: 1

    积分
    60

Qter1级会员

发私信

Qt开源社区——开源 共享 自由

微信扫一扫
查看精品教程!