某个类的友元
- 可以访问该类的所有成员
- 可以通过该类的对象访问该类基类的protected成员
- 不可以直接访问该类的基类的成员(包括基类的protected成员)
- 不可以访问该类的派生类的成员
某个类的private成员
- 只能被该类的成员或该类的友元访问
某个类的protected成员
- 可以被其派生类的成员函数通过该派生类的对象访问
- 可以被其派生类的友元通过该派生类的对象访问
- 可以被该类的成员或友元访问
某个类的public成员
- 可以被类的所有用户访问
派生访问说明符(public private protected)
- 相当于给派生类规定了这个基类的最低访问权限,若在基类中的访问说明符访问等级低于这个派生访问说明符,则将其提高到这个派生访问说明符的等级
- class默认是私有继承基类;struct默认是公有继承
struct
和class
定义的类,区别仅在于他们的默认成员访问说明符和默认派生访问说明符
派生类可改变基类个别成员的可访问性
- 用
using
进行声明 - 只能改变基类中访问说明符允许的派生类可以访问的成员的可访问性(主要是针对派生访问说明符定义的访问权限的修改)。例如派生类无法访问基类的private成员,故它无法用
using
改变该成员的可访问性。
覆盖 隐藏
派生类的作用域嵌套在其基类作用域之内
派生类会隐藏基类的同名成员
- 派生类的函数与基类的虚函数同名,且形参列表相同——覆盖
- 派生类的函数与基类的虚函数同名,但形参列表不同——隐藏
- 派生类的成员与基类的普通成员同名(不论形参列表是否一致)——隐藏
虚调用
- 如果函数的入口地址是在编译阶段静态确定的,就是是实调用
- 如果函数的入口地址要在运行时通过查询虚函数表的方式获得,就是虚调用
- 如果是虚函数,且是用引用或指针调用,则编译器产生的代码将在运行时确定到底运行的是该虚函数的哪个版本,依据是对象的动态类型
- 如果不是虚函数,或者是通过对象(而不是引用或指针)调用,编译器将产生一个常规的函数调用
一个类指针调用的类函数:
(1) 在 指针的类型 这个类里找这个函数
(2) 若没有这个函数,报错;若有这个函数,判断它是否为虚函数(!!!找这个函数不仅仅要看函数名,还要看形参列表是否符合)
(3) 若不是虚函数,就调用该成员函数(即静态类型)
(4) 若是虚函数,则去找指针所绑定的对象所属的类中的对应虚函数(即对象的动态类型)。找到则调用;若该类并没有覆盖那个虚函数,则回去调用刚才找到的那个虚函数(指针的类型那个类的虚函数)