4 Function语义学
1. C++标准要求:非静态成员函数至少必须和一般的非成员函数有相同的效率。
2. 成员函数会被编译器mangle为非成员函数,尤其是重载更需要mangle手法进行改名。extern “C”阻止函数改名。
3. Static成员函数:1)参数没有this;2)不能访问非静态成员;3)不能是const、virtual等;4)可以不用对象访问。
4. Static成员函数,由于没有this,所以可以作为callback函数的候选,或者作为线程的主函数。
5. C++中多态表示:以一个public base class的指针或引用,寻址出一个derived class对象,并访问相应的virtual函数。
6. Vtbl中的虚函数一定在编译期间获知,其函数的个数、位置和地址是固定不变的,执行期间不能增、改、删。
7. 执行期三步完成虚函数调用:1)由vptr找到vtbl;2)定位vtbl中的slot(索引值);3)通过该索引下的值调函数。
8. Vtbl的内容包括三部分:1)在该类中定义的函数实体,它是一个新的virtual函数,或者会override其基类的虚函数;2)继承自基类的虚函数实现,本类不进行override;3)纯虚函数的占位。注意:普通非virtual函数不在vtbl中。
9. 子类新增加virtual函数的时候,会在原本的vtbl中最后面增加一个slot,加入这个新的virtual函数地址。
10. 多重继承中,一个派生类会有n-1个额外vtbl(n=直接基类个数),它与第一父类共享vtbl,会修改其他父类的vtbl。
11. 在这三种情况下,第二或后继基类会影响virtual函数的调用:
Ø 通过“指向第二个基类”的指针,调用派生类的自己新的虚函数。这时,指针必须调整到Derived的vptr处。
Ø 通过“指向派生类”的指针,调用从第二个基类中派生下来的虚函数。这时,指针必须调整到第二基类vptr处。
Ø 允许从基类派生的虚函数修改返回值的情况,在VC中不支持,所以具体情况未知。
12. 虚拟继承下的虚函数,由于有了一个到虚拟基类的offset,所以virtual函数的调用复杂度更高,性能更差。
13. A)指向非static成员变量的指针,其值是它在该类内存中的offset:float ClassA::*pt1 = &ClassA::m_f1;B)1)指向静态成员函数的指针,其值是该函数在内存中的真正地址;2)指向virtual成员函数的指针,其值是vtbl中的索引值;3)指向非virtual非静态成员函数的指针,其值是该函数在内存中的真正地址,绑定到this之后即可以进行函数调用。
Inline对编译器只是请求,并非命令。inline中的局部变量+有表达式的参数 => 大量临时变量 => 程序规模暴涨。
实验代码: