您的位置:首页 > 编程语言 > C语言/C++

《深度探索C++对象模型》--4 Function语意学

2014-02-19 11:25 120 查看


1、member的各种调用方式

(1)nonstaticmember
functions

C++的设计准则之一就是:非静态成员函数至少必须和一般的非成员函数有相同的效率,编译器内部将成员函数转换为对等的非成员函数实体。通过安插this指针和mangling等完成。

(2)namemangling(名字的特殊处理)

使名字独一无二,函数的signature为函数名称+参数个数+参数类型;

(3)virtualmember
functions

通过vptr来调用。有时inline会极大地提高效率。

(4)staticmember
function

注意一个问题:如果class设计staticdata
member声明为nonpublic,那么必须提供一个member
function 来存取该member,虽然可以不依靠classobject来存取staticmember,但存取函数必须绑定于一个classobject上。此时引入了staticmember
function。

主要特性是没有this指针。注意它不能直接存取nonstatic
members;不能被声明为const、volatile或virtual;不需要经由classobject才被调用(但是可以)。

对其取地址,得到的是在内存中的地址,是一个nonmember函数的指针。

2、virtual
function members


(1)单一继承时

当一个类派生自另一个类,一共会有三种可能:

它可以继承base class所声明的virtualfunctions的函数体,正确的说是该函数体的地址被拷贝到derivedclass的virtualtable相对应的slot之中;

它可以使用自己的函数体,这表示它自己的函数体地址必须放在对应的slot之中;

它可以加入一个新的virtual function,此时virtualtable的尺寸会增大一个slot,新的函数体地址会被放进该slot之中。

(2)多重继承时

一个derivedclass内含n-1个额外的virtualtable(n表示上一层baseclasses的个数),一个主要的与最左端的base
class共享,其他的依次与其他base class的有关。

(3)虚拟继承时

建议不要在virtualbase class中声明nonstaticdata
members。

3、指向member
function的指针


(1)复习成员函数指针:

指向类的非静态成员指针在声明时必须指明classobject;

double(Point::*pmf)();//声明,指出返回值类型,类名称,参数列表

double(Point::*cord)() = &Point::x; //初始化,赋值通过&取地址

(2)支持“指向virtualmember
functions”的指针

虚拟机制仍然能够在使用“指向memberfunction之指针”的情况下运行;对一个virtualmember
function取地址,所得到的是其在virtualtable的索引值。

对于如何区分内存地址还是vtbl的索引?采用一种基于假设继承体系中最多只有128个virtualfunctions的方法。(即首位是1还是0)

(3)多重继承之下,指向member
functions的指针

对于通过memberfunctions指针来调用的操作,需要导入一个vcall
thunk。函数指针地址要么是真正的member function地址(nonvirtual时),要么是vcallthunk的地址。vcall
thunk会选出并调用相关vtbl中适当的slot。

4、Inline
Functions


(1)用inline来完成set和get操作很高效。

(2)inline实现中,对于面对会带来副作用的实际参数,编译器通常会引入临时对象;如果实际参数是一个常量表达式,会在替换之前先进行求值操作,后续的inline时直接将常量绑定;如果不是上述两点就直接替换。

(3)如果inline函数中有许多局部变量,则会产生巨多临时对象,这影响效率,要注意。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: