c++中的多态

        多态,顾名思义,就是多种形态。总的来说就是一句话:使基类指针或引用可以访问子类对象。

        介绍多态前,先说函数调用捆绑。

        把函数体与函数调用相联系称为捆绑(binding)。当捆绑在程序运行之前(由编译器和连接器)完成时,这个叫早捆绑(early bingding)。在C语言中,捆绑的方式只有一种——早捆绑。而在运行时发生的捆绑,叫做动态捆绑(dynamic binding)或者运行时捆绑(runtime binding)。在c++中,通过在基类中声明函数时使用virtual关键字,告诉编译器使用晚捆绑。晚捆绑只对virtual函数起作用,而且只在使用含有virtual函数的基类的地址时发生。

        为了实现多态,编译器对每个包含虚函数的类创建一个vtab(虚函数表)和一个vptr(指针),并在构造函数中初始化vptr指向vtab,并把声明的虚函数的地址放到vtab中。一般这个vtab的地址是在类对象地址的最前面,所以现在这个时候,this指针和vptr指针指向的地址应该一致——指向这个类对象的首地址。

        当子类继承这个基类时,子类也会继承这个vptr,而子类的vptr也指向自己的这个vptr,其vptr的位置与基类中vptr的位置一样——在对象的最前面,此时不论在子类中该函数是否有virtual关键字,这个函数都是虚函数。如果在子类中又增加了virtul函数,则编译器会在从基类继承的、子类自己的vtab最下面插入这个新的virtual函数的地址。

        因为是晚绑定,所以函数在编译的过程中,不会绑定其调用地址。在程序运行中,调用virtual的时候,如果是通过基类指针或者引用调用虚函数时,如果该基类指针或引用指向的是子类对象,则会查找基类指针指向的子类的vtab,从而取得正确的函数地址,然后调用该函数,这就实现了多态。

        下面看代码:

         

#include <iostream>
using namespace std;

class Base
{
public:
    virtual void show(){cout<<"base show"<<endl;}
};

class A : public Base
{
public:
    void show(){cout<<"A show"<<endl;}
};

class B : public Base
{
public:
    void show(){cout<<"B show"<<endl;}
};

void pt(Base& b)
{
    b.show();
}

int main()
{
    A a;
    B b;
    
    Base& base = b;
    pt(base);

    return 0;
}

        此时打印的是B show。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

双鱼理

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值