1、
访问控制中有三种角色:基类及其友元,派生类,类用户(对象);
访问说明符分为public/protected/private,类的成员也相应的分为了3种。
2、
访问说明符又分为两种:一个是基类中的成员访问说明符;另一个是派生类派生列表中的访问说明符。
3、以上两种访问说明符把
类的成员分成了分为了6种:派生类中的public/protected/private成员;派生类的public/protected/private基类及其成员。
4、接下来我们梳理一下三种角色对上述成员的访问权限。
4.1 我们假设只有一个基类,那么它的成员有public/protected/private三种。访问关系如下表:(有权限简称有,无权限简称无)
|
public成员
|
protected成员
|
private成员
|
基类及其友元
|
有
|
有
|
有
|
派生类及其友元
|
有
|
有
|
无
|
类用户
|
有
|
无
|
无
|
具体来说就是:1)基类本身及其友元对基类中任何成员都有访问权限;
2)派生类及派生类的友元可以通过派生类的对象访问基类中受保护的成员,对private成员无访问权限;
3)
类用户(由基类定义的对象)只能访问基类中的public成员。
4.2 加上派生列表中的访问说明符之后,访问的成员加上了派生类的基类,然后,我们看访问权限有什么变化?
1)派生列表后的访问说明符相当于说明了基类属于派生类的成员类型,举个例子来说,Class D:public B,那么基类B就相当于D中的public成员,但是需要注意的一点就是,基类中的成员仍然受到基类中的访问说明符的控制,也就是说,尽管B是public的,但是B中的private成员D仍然没有权限进行访问。
2)因为类及其友元可以访问本身所有数据成员,所以派生访问说明符对于派生类的成员(及其友元)能否访问其直接基类的成员没有什么影响;所造成的不同点就在于派生类的派生类和派生类的对象访问权限会有所不同,这时候可以
把基类看作是派生类中的成员。
总结起来就有如下表:
|
派生类public
|
派生类protected
|
派生类private
|
public基类
|
protected基类
|
private基类
|
派生类及其友元 |
有
|
有
|
有
|
无影响
|
无影响
|
无影响
|
派生类的派生类及其友元
|
有
|
有
|
无
|
无影响
|
无影响
|
无
|
派生类用户
|
有
|
无
|
无
|
无影响
|
无
|
无
|
5、派生类向基类转换的可访问性:能否转换的关键就是基类的公有成员是否对派生类的某种角色(派生类及其友元、派生类的用户,派生类的派生类及其友元)是否是可访问的,如果可以访问,就可以转换;换句话说,
如果当前的角色能够使用基类中的公有成员,那么就是可以转换的。
6、关于友元:
1)友元关系不能继承,是基类的友元,如果不声明的话,就不是派生类的友元,也就不能访问派生类的成员。
2)基类的友元可以访问基类中的成员以及派生类中的基类部分。
7、当然成员的可访问性也不是一成不变的,使用using声明就可以改变其访问性,但是还受到成员访问说明符的制约。
8、struct和class的唯一区别就在于默认的访问权限不同,最好还是显示声明访问权限。