每个类通过成员访问运算符控制其成员对于派生类和类的用户来说是否是可访问的。
受保护的成员
一个类使用protected
关键字来声明那些希望与派生类分享但不想被其他用户访问的成员。可以说protected是夹在private成员和public成员的中和产物。主要有以下三条性质
- 受保护成员对于类的用户者不可访问
- 受保护成员对于派生类的成员和友元是可访问
- 派生类的成员或者友元只能通过派生类对象来访问基类的受保护成员,派生类对于一个基类对象中的受保护成员没有访问权限。即派生类的成员和友元只能访问派生类对象中的基类部分的受保护成员(管好自家),而对一个普通基类对象中的受保护成员是没有访问权限的。
第三点举例
1 | //定义基类 |
类本身 | 类的实例化对象(类的用户) | 类的派生 | |
---|---|---|---|
public成员 | √ | √ | √ |
private成员 | √ | X | X |
protected成员 | √ | X | √ |
√表示可访问,X表示不可访问
三种继承方式——公有、私有和受保护继承
不加声明,class默认私有继承,struct默认公有继承
类对其继承而来的成员的访问权限收到两个因素影响:1.基类中的成员访问符 2. 派生列表的访问说明符
1 | //定义基类 |
派生列表的访问说明符不影响派生类对基类部分成员的访问权限,这只与基类中的成员访问符有关,派生列表中的访问说明符的目的是
控制派生类用户(包括派生类的派生)对于基类成员的访问权限
1 | Pub_Derv d1; |
派生类向基类转换的可访问性
派生类向基类转换: 基类的指针指向派生类或者基类的引用绑定到派生类对象(实际上是指向或者绑定到派生类的基类部分)
- 只有当派生类公有的继承基类,用户代码才能使用派生类向基类转换。私有和保护继承都不行
- 派生类的成员函数和友元都能使用派生类向基类的转换,与继承方式无关
- 如果派生类是公有或者保护继承基类,那么派生类的派生类的成员函数和友元可以实现派生类向其基类的转换
类的设计小tip
类有三种用户:类的实现者、派生类以及类的使用者。基类应该将接口成员声明为公有;同时将实现部分分成两组:1.声明为protected
供派生类访问 2. 声明为private
共基类自身和基类的友元访问
类的用户 | 访问权限 |
---|---|
类的实现者 | 全部 |
类的使用者 | 类的公共接口 |
派生类 | 类的保护成员 |
友元与继承
友元关系不能传递也不能继承,每个类负责自己的成员的访问权限。基类的友元只能访问基类,不能访问它的派生类本身成员,但是可以访问派生类中的基类部分的成员。
1 | class Base{ |