相当微不足道。

虽然这个图是疯狂的寻找,这真的很简单:* __vptr每班点的虚拟表类。在最派生版本这类可以调用函数的对象的虚拟点表条目。

所以考虑会发生什么,我们创建的一个对象时,D1型:

1
2
3
4
int main()
{
     D1 cClass;
}

因为阶层是D1对象,阶层有* __vptr设置为D1虚拟表。

现在,让我们把基类指针D1:

1
2
3
4
5
int main()
{
     D1 cClass;
     Ba

注意,因为pclass是基类指针,它指向阶层的基部。然而,也要注意* __vptr是在类的基础部分,所以pclass访问这个指针。最后,请注意,pclass -> __vptr指向D1虚拟表!因此,即使pclass类型为基础,它还能访问D1′虚拟表。

所以当我们试着打pclass -> function1()?

1
2
3
4
5
6
int main()
{
     D1 cClass;
     Base *pClass = &cClass;
     pClass->function1();
}

首先,该计划承认,function1()是一个虚拟函数。第二,采用pclass -> __vptr到D1′虚拟表。第三,它看起来打电话在D1′虚拟表function1()版本。这已被设置为D1::function1()。因此,pclass -> function1()解决D1::function1()!

现在,你可能会说,“但如果基地确实指向代替D1对象基类对象。它还叫D1::function1()?“。答案是否定的

1
2
3
4
5
6
int main()
{
     Base cClass;
     Base *pClass = &cClass;
     pClass->function1(

在这种情况下,当阶层被创建,__vptr分基地的虚表,不是D1′虚拟表。因此,pclass -> __vptr也将指向基地的虚拟表。为function1()分基地的虚拟表中的条目::function1()。因此,pclass -> function1()解决基地::function1(),这是最派生版本function1(),基类对象应该能打电话。

通过使用这些表,编译器和程序可以确保函数调用解决适当的虚拟函数,即使你只使用基类的指针或引用!

调用虚函数调用非虚函数是有几个原因:第一,我们要慢,使用* __vptr到适当的虚拟表。 第二,我们要索引的虚拟表,找到正确的函数调用。 只有这样我们才能调用该函数。 因此,我们要做的3个操作找到的函数调用,而不是2操作正常的间接函数调用,或一个操作的一个直接的函数调用。 然而 随着 现代计算机, 增加的时间 通常是相当 微不足道
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值