C++ 对象模型 — Function 语意学
文章目录
调用方式
- 普通函数
- 虚函数
- 静态函数
非静态成员函数
C++ 设计准则之一:非静态成员函数至少和非成员函数效率一样。
成员函数内化为非成员函数的过程:
- 改写函数签名:安插 this 指针
- 对非静态成员的存取经由 this 指针处理
- 将成员函数重新写成一个外部函数,对函数名称进行特殊处理,使它在程序中独一无二
特殊处理
成员前面一般加上 class
的名称形成独一无二的符号,否则无法决议(unsolve)
虚拟成员函数
vptr
也可能会被特殊处理,因为在复杂的派生体系中可能存在多个vptrs
- 每次调用都会通过虚函数的索引进行调用
静态成员函数
- 不能直接存取非静态成员
- 不能被声明为
const
,volatile
或virtual
,因为实际上这些都是修饰this
的, 而静态成员函数没有this
. - 不需要经由类对象调用
虚拟成员函数
- 继承基类所声明的虚函数的实体,准确地说,是该函数的实体的地址拷贝到派生类的虚 表相对应的 slot 中
- 可以是自己的函数实体,表示自己的函数实体地址放在对应的 slot 中
- 可以是加入一个新的虚函数,这时虚表的尺寸会增大一个 slot,新函数的实体地址会被 放在 slot 之中
多重继承的虚函数
复杂度主要在第二个以及后继的基类的类上,必须在执行期调整 this
指针。
base1
不需要调整this
指针,因为它已经指向派生类的起始处。其虚表slot
需放置正确的析构函数地址base2
及以后需要调整,虚表的slot
要保存正确的地址
在多重继承下,派生类中内含 n-1
个额外的虚表, n
表示其上一层基类的数目。
虚继承的虚函数
建议:不要在一个虚基类中声明非静态数据成员
函数的效能
内联 > 友元 = 静态 = 非静态 > 虚函数 > 多重虚函数 > 虚继承虚函数