抛砖引玉篇--member function
/ --*-- 2018.7.27 --*-- /
摘要:论述了C++对象模型中的member function,
包括member function的类型及其在对象模型中所充当的角色,还有各function的执行效率。
%note:c语言是面向过程的语言,代码重点在于如何高效的完成某个步骤。
c++是面向对象的语言,除了效率,也注重代码本身的架构,
力求在代码效率和可重用性、可扩展性之间寻求一个平衡点。
% c++支持三种类型的member function:
static、nonstatic function, virtual function。
% nonstatic member-function:对nonstatic data member进行函数封装,执行操作方法。
nonstatic member-function的执行效率并不比nonmember function的差,
nonstatic member-function最终也被编译器处理成弄nonmember function,
过程如下:
@1. 修改其signature,以插入一个额外参数:this指针。
@2. nonstatic-member function对nonstatic data member的操作由this指针直接完成,
这一点比nonmember function的传参高效。
@3.对函数进行 name-mangling, 确保函数名称是独一无二的。
% name-mangling技术提供了一种确保data member和member function名称独一无二的方法,使用到的地方有:
@1.函数重载时,函数名称加上参数列表;
@2.基类和派生类中有相同member时,变量名加上类名;
name-mangling技术是c++实现作用域的一种方法?
% virtual member-function:
是实现C++“多态”特性的关键所在:如何由class base指针调用derived class object的virtual member-function。
其中:
ptr是this指针, vptr是指向虚函数表的指针。
虚函数表存放的是虚函数的函数指针,通过索引1得到该指针,并传进this指针。
虚函数也会被name-mangling。(考虑·一个抽象基类有多个derived class时)
note:virtual member-function通过vptr指针间接引用,所以在效率上是比较低下的,
但它确是c++多态的基本实现技术。
%static member-function:
note: static member-function为操作static data-member提供了方法,
但其没有传进this指针,所以:
##1.static function不能nonstatic data member;
##2.static function 不可能同时为const function;
可见,static-member function并没有传进this指针。
virtual member-function:
virtual function的一般实现模型:
每个含有虚函数的类拥有一张virtual table,用于存储virtual function的函数指针,
每个基类的对象都有一个vptr,指向virtual table。
note:polymorphism -- 通过base class指针可以调用derived class object的virtual function?
当发生继承时:
当有以下调用发生时(ptr是一个基类指针):
在编译期,编译器的工作是:
@1.通过ptr找到对象的vptr,
@2.通过vptr找到virtual table,并找到z()在virtual table中位置
在执行期,根据编译期找到的z()所在的位置,执行实际的函数。
在单一继承情况下,virtual function模型即容易实现,而且有效率。
但在多重继承的情况下的支持就不是很完美了。
note:单一继承时: base class object和derived class object所在内存地址空间的首地址是相同的,
所以base class指针可以直接找到vptr,
但多重继承时,base class object和derived class object所在内存空间的首地址可能存在一定的offset,所以需要先对指针进 行调整。
% 函数执行效率:
inline function:避免了函数调用,同时也增加了编译器优化的机会。
nonmember function、nonstatic-member function、static-member function
这三者的效率相当。
virtual member function:多了一层间接引用,效率最低。
% friend function:
:c++的封装特性,要求data member对外屏蔽,只能通过公共的member function进行操作。
但有时候member function满足不了需求,例如:
对nonstatic member-function总是得通过对象调用。
对static member-function又无法操作nonstatic data-member。
##所以,需要提供另外一种特殊的方法可以访问到data-member。
% inline函数:为效率而存在(空间换时间),是C语言宏函数的进化。
note:可见定义的inline函数,并不一定会被实现,编译器会进行判断是否实现为inline。
%在inline扩展期间,每一个型参都将被相应的实参所替代。
可分三种情况讨论:
@1.对于“会带来副作用的实参”,先引入临时变量,对实参进行求值操作, 再完成替换。
避免了在执行期间,对实参进行重复求值的操作。
@2.对于常量表达式,将常量代入,直接执行inline函数体内的操作,并得到结果。
@3.除了上面两种情况以外的普通形参,直接替换。
example:
##1.
##2.
##3.
% inline中的局部变量
##1.
##2.
##3.
note:定义在类申明体中成员函数都是inline函数。
参考书籍:《Inside The C++ Object Model》