【深度探索c++对象模型】Function语义学之成员函数调用方式

非静态成员函数

c++的设计准则之一就是:非静态成员函数至少和一般的非成员函数有相同的效率。编译器内部已将member函数实体转换为对等的nonmember函数实体。

转化步骤:

1.改写函数原型以安插一个额外的参数到member function中,使class object可以调用该函数,该额外参数为this指针。

2.将函数中每一个对nonstatic data member的存取操作改为经由this指针来存取

3.对函数名称进行处理,使它在程序中成为独一无二的词汇。

名称的特殊处理

一般而言,member的名称前面会由编译器加上class名称,形成独一无二的命名。

class bar

{

public:

  int ival;

};

编译后ival可能会变成ival_bar.之所以如此处理,是为了防止以下的操作:

class foo:public bar

{

public:

  int ival;

};

这样编译后会变成这样:

class foo

{

public:

  int ival_bar;

  int ival_foo;

};

由于member function可以被重载化,所以需要更广泛的mangling手法,以提供独一无二的名称。编译器利用函数名称、参数个数、参数类型来使得函数有着独一无二的名称。这样一来,可以捕捉链接时期函数名称+参数数目+参数类型方面的错误,但是如果返回类型出错,就没办法检查出来。

virtual member function(虚函数)

point3d obj;
point3d *ptr = &obj;

若normalize()是虚函数,则ptr->normalize()将会被内部转化为(*ptr->vptr[1])(ptr)

其中,vptr表示由编译器产生的指针,指向virtual table,它被安插在每一个声明有(或继承自)一个或多个virtual function的class object中。

1是virtual table slot的索引值,关联到normalize()函数,第二个ptr表示this指针。

注意:经由一个class object调用virtual function,这种操作总是被编译器像对待一般的nonstatic member function一样加以决议,也就是不会用到虚指针。

静态成员函数

在引入静态成员函数之前,c++要求所有的成员函数都必须经由该类的对象来调用。而实际上,只有当一个或多个非静态数据成员在成员函数中被直接存取时,才需要类对象。类对象提供了this指针给这种形式的函数调用使用。这个this指针把在成员函数中存取的非静态类成员绑定于对象内对应的成员之上。如果没有任何一个成员被直接存取,事实上就不需要this指针,因此也就没有必要通过一个类对象来调用一个成员函数。

独立于类对象之外的存取操作,在某个时候特别重要:当class设计者希望支持没有class object存在的情况。程序层面上的解决方法是把0强制转换为一个类指针,因而提供了一个this指针实例,语言层面上的解决方法是静态成员函数。

静态成员函数的主要特性是没有this指针,以下次要特性统统根源于主要特性:

1.它不能够直接存取所在类中的nonstatic members(需要this指针)

2.它不能够被声明为const volatile或virtual(因为虚函数通过vptr调用,而vptr属于对象,但是静态成员函数属于类)

3.可以通过类名或class object来调用

posted @ 2014-07-16 14:21  合唱团abc  阅读(599)  评论(0编辑  收藏  举报