间接调用虚函数

运行结果是什么?

father *pf = new father();
pf->A();
pf->B();
delete pf;

father *ps = new son();
ps->A();
ps->B();
delete ps;

son *ps1 = new son();
ps1->A();
ps1->B();
delete ps1;

son *pss = new sonson();
pss->A();
pss->B();
delete pss;

运行结果

this is father::B()
this is father::B()
this is father::B()
this is father::B()
this is father::B()
this is son::B()
this is father::B()
this is sonson::B()

解释与结论

id指针名指针的类型实际的类型运行结果解释
1pffatherfatherthis is father::B()
this is father::B()
2psfathersonthis is father::B()
this is father::B()
virtual关键字在子类可知此处不会有多态
3ps1sonsonthis is father::B()
this is son::B()
此例中,指针的类型和对象的类型都是son,为什么最后调用的是fathher::B()?
4psssonsonsonthis is father::B()
this is sonson::B()
virtual关键字在子类可知此处应该有多态效果,为什么最后调用的还是fathher::B()?

解释:

在上面的测试用例中,ps1->A();pss->A();的运行结果都是father::B()。它们都有一个共同的特点,就是指针通过A()去调用B()。

当程序通过A()调用B时,它已经处理father::A()的作用域里面了,因此此时它实际上已经不再通过ps1或者pss去访问B(),而是通过father::this。

father::this显然是father类型的指针,所以它会先去查看father::B()。它发现father::B()不是虚函数,也就不会去查vtable,而是直接调用father::B()了。这一部分的原理与virtual关键字在子类相同。

其它测试

virtual关键字在父类

virtual关键字在子类

virtual关键字在子类

完整代码

#include <iostream>
using namespace std;

class father
{
public:
  void A()  { B(); }
  void B()
  {
    cout<<"this is father::B()"<<endl;
  }
};

class son : public father
{
public:
  virtual void B()
  {
    cout<<"this is son::B()"<<endl;
  }
};

class sonson : public son
{
public:
  void B()
  {
    cout<<"this is sonson::B()"<<endl;
  }
};

int main()
{
  father *pf = new father();
  pf->A();
  pf->B();
  delete pf;
  father *ps = new son();
  ps->A();
  ps->B();
  delete ps;
  son *ps1 = new son();
  ps1->A();
  ps1->B();
  delete ps1;
  son *pss = new sonson();
  pss->A();
  pss->B();
  delete pss;
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值