函数的动态绑定和静态绑定

  先看一个例子:Widget类中有个虚函数和一个非虚函数。指针变量pWidget的值是NULL。通过指针调用非虚函数和虚函数。

class Widget{
public:
 virtual void virtual_flip(){
  cout << "virtual func" << endl;
 }
 
 void nonvirtual_flip(){
  cout << "nonvirtual func" << endl;
 }
};
 
int main(){
 Widget* pWidget = NULL;
 pWidget->nonvirtual_flip();
 pWidget->virtual_flip();
 return 0;
}

  结果,编译通过,但是调用非虚函数能够正确运行,而调用虚函数则不行。

    先看看,编译器如何把虚拟函数调用重新改写的:调用pWidget->virtual_flip(),时,编译器会将其重新写成如下形式:
(*(pWidget->vptr[1])(pWidget),其中1表示virtual_flip()在虚表中的索引。包含虚函数的类会在其对象中包含一个指向虚函数表的指针vptr(该指针在构造函数中设定),由于要到对象中取的vptr,所以当指针为空,则取该指针所指对象就会出错。
    而对于非虚函数的调用是在连接过程中将实际的函数地址填入即可(编译是分模块分别进行的),并不会到对象中去取。所以可以正确运行。
    同时要注意,类的非静态成员函数都隐含一个this指针,所以如果在nonvirtual_flip()内部要访问一个类的数据成员,那么传递的NULL指针就会出错。
posted @ 2015-07-13 08:49  marchlyp  阅读(271)  评论(0编辑  收藏  举报