虚函数的研究(一)

    C++里有虚函数的概念,用法也很简单,在函数声明之前加关键字virtual。之所以有这样的概念的原因,是为了面向对象的程序能“向后兼容”,通过它你可以事先写好程序框架,后面再慢慢实现,而不用改原来的款价。看个例子:

 

  1. #include <stdio.h>
  2. class Base {
  3. public:
  4.     virtual void foo() {
  5.         printf("virtual Base::foo()./n");
  6.     }
  7. };
  8. class Derive : Base {
  9. public:
  10.     void foo() {
  11.         printf("virtual Derive::foo()./n");
  12.     }
  13. };
  14. void bar(Base * pbs)
  15. {
  16.     pbs->foo();
  17. }
  18. int main()
  19. {
  20.     Base bs;
  21.     bs.foo();
  22.     Derive dr;
  23.     dr.foo();
  24.     bar(&bs)
  25.     return 0;
  26. }

    Derive类重定义了Base类的虚函数foo(),main函数开始的两个函数调用实际上可以看作是对两个普通类的调用,可以说和普通的成员函数调用没任何区别。但是,当调用函数bar()时,虚函数的优点就出来了,虚函数的规则允许父子类对象之间的指针互相赋值,而且,会根据具体执行的时候看指针的具体指向来决定到底执行哪一个foo(),这样我们可以在还没有Derive类的时候就写好整个应用程序框架,以达到向后兼容的目的。
    不过这里要说的不是这个,而是,对编译器而言,问题就来了,既然你的规则定的这么灵活,那我就没办法在编译的时候决定到底是调用哪一个foo()了,确切的说是无法确定在代码区的偏移。无奈之下,提出了vtable的概念,vtable的作用就是,允许程序在运行的到bar()这一句的时候决定到底执行那一个foo()。这里我要强调的是顺序问题,也就是先有“向后兼容”,再有虚函数,最后才有vtable、晚绑定等概念,说白了就是由需求决定的,而不是凭空出来这么多些规则。
    实际上,虚函数有点像c里的回调函数,如果把函数名看作是普通的指针,回调函数就很好理解了,只不过这里的指针是函数的入口地址,貌似有点特别。顺着这个思路下去,纯虚函数、虚基类也很好理解了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值