第 4 章 Function语意学
Posted Ivan B.G. Liu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第 4 章 Function语意学相关的知识,希望对你有一定的参考价值。
1.Member Funcition的各种调用方式
-
Nonstatic member funcion:
编译器将其转为nonmember Function的形式,转化步骤是:
(1)添加额外的参数 ---- this指针
(2)对每一个nonstatic data member的存取由this指针操作。(this指针提供了一个存取管道)
(3)对函数名进行 mangling处理,使它在程序中成为独一无二的名词。
-
Virtual member function:
编译器将其转为nonstatic member function,随后转化为nonmember function,具体如下:
对于虚函数f(),obj.f()在编译器内部转化为:
(* obj.vptr[1])(&obj)
其中,1表示virtual table的索引值,即指向第1个slot。关联到normalize()函数。
-
Static member function:
编译器会将其视为nonmember function的形式。
static member function 会提出于class声明之外,并经过mangling后有独立的名称。
如果取一个static member function 的地址,获得的是其在内存中的真实物理地址,而不是一个指向“class member function”的指针,如下:
&Point::count();
会得到一个数值,类型是:
unsigned int(*)(); //普通的函数指针,表示真实的物理地址
而不是:
unsigned int(Point::*)(); //类成员函数指针,表示由this调控
2. Virtual Member Funcitons
-
C++中,多态表示以基类指针,寻址出一个派生类对象。每个类的virtual table中的active virtual function 包括:
(1)override base class的函数实体。
(2)继承自base class 的函数实体。
(3)一个pure_virtual_called()。
-
一个类继承函数virtual table的三种可能性:
(1)继承base class 所声明的virtual functions的函数实体。(该函数实体的地址会被拷贝到derived class的virtual table相对应的slot之中)
(2)使用自己的函数实体(改写了base class的virtual funciton)。(改写后的函数实体地址必须放在对应的slot之中)
(3)可以加入一个新的virtual function。(这时候virtual table 的尺寸会增大一个slot放进这个函数实体地址)
-
编译时期设定virtual function的调用:
调用z()时,虽然不知道其所指对象的真正类型,但是知道z()函数地址存放在virtual table的第4个slot中,编译器作出的转化为:
ptr->z() ------>(*ptr->vptr[4])(ptr)
唯一一个在执行期才能知道的东西是:slot4所指的到底是哪一个z()函数实体,即ptr指向哪个虚表。
-
多重继承下的 Virtual Functions
(1) 在多重继承中支持virtual functions,“必须在执行期调整this 指针”。一般规则是:
经由指向“第二或后继base class的指针”来调用derived class virtual function。其中this指针的调整操作必须在执行期完成。
(2) 多重继承下,一个drived class内含n-1个额外的virtual tables。(n表示继承的基类数量)
(3) 多重继承下的virtual table布局图:
- 普通函数指针和类成员函数指针:
- member 地址表示:
- inline函数请求的不同结果:
- inline函数有局部变量的危险:
以上是关于第 4 章 Function语意学的主要内容,如果未能解决你的问题,请参考以下文章