现在的位置: 首页 > 综合 > 正文

C++虚函数和消息映射机制

2012年12月22日 ⁄ 综合 ⁄ 共 731字 ⁄ 字号 评论关闭

派生类重写基类的函数一般有两种方法:虚函数(C++),消息映射(smalltalk,Objective-C,MFC,Qt)

1.C++虚函数实现机制

每个有虚函数的类都有一个虚表,并且在内存对象的布局中,第一项就是指向这个虚表的虚指针。

class A

{

 public:

     virtual void f();

     virtual void g();

private:

     int a;

};

class B

{

public:

     void g();

private:

     int b;

};

B bB;

A *pa = &bB;
bB对应的内存布局:

vptr
A::a
B::b

vptr指向的虚表:

A::f()
B::g()

pa的结构就是A的布局,即pa只能访问到bB对象的前两项,访问不到第三项B::b,在编译阶段编译器将索引和表项做好,当编译到pa->g()时,将其转换成call *(pa->vptr)[1],这就是C++的静态编译,所以执行效率高,但是当A的虚函数比较多时(比如1000个),而B重写的比较少(比如2个),这时B类型的每个对象的虚表中的998个表项都是为了放A中的虚函数的入口地址,这样就浪费了很多空间。

2.消息映射机制

这种方法是按照函数名称查表,这种方法不需要所有的B类型的所有对象都存储虚表,但是这种方法要在所有的虚函数中进行查找,并且在Objective-C中,采取动态绑定机制,在运行时查找指定函数名,因此执行效率比较低,但是Objective-C中有一个@selector,对每个函数名进行编码,这样可以快速地找到指定函数名。因为在MFC中的派生体系比较庞大,但是重写函数不多,因此MFC采用消息映射机制才能达到较高的效率。例如很多GUI库都采用这种机制,例如MFC,Qt。

抱歉!评论已关闭.