C++多态简析——静态多态与动态多态

栏目: 编程语言 · 发布时间: 8年前

内容简介:C++多态简析——静态多态与动态多态

多态: 顾名思义,多态就是多种形态,也就是对不同对象发送同一个消息,不同对象会做出不同的响应。

并且多态分为静态多态和动态多态。

静态多态就是在系统编译期间就可以确定程序执行到这里将要执行哪个函数,例如:函数的重载,对象名加点操作符执行成员函数等,都是静态多态,其中,重载是在形成符号表的时候,对函数名做了区分,从而确定了程序执行到这里将要执行哪个函数,对象名加点操作符执行成员函数是通过this指针来调用的。

函数的重载比较简单,不再赘述,这里我们通过一个简单的例子来看一下对象名加点操作符执行成员函数的静态多态:

class A
{
public:
    void Set(int a)
    {
        _a = a;
    }
public:
    int _a;
};

int main()
{
    A a1;
    a1.Set(15);
    return 0;
}

这里定义了一个A类,有一个成员函数和一个成员,我们将程序的部分汇编代码截取出来如下图:

C++多态简析——静态多态与动态多态

我们可以看到这里直接是一个lea指令将a1对象的地址放入寄存器eax中,也就是对象的this指针,然后用call指令就可以跳转到Set函数,也就是说其汇编代码在此时就知道应该要去到哪个地方之行哪个函数,这就是静态多态,也叫 编译时多态

动态多态则是利用虚函数实现了运行时的多态,也就是说在系统编译的时候并不知道程序将要调用哪一个函数,只有在运行到这里的时候才能确定接下来会跳转到哪一个函数的栈帧。

在说动态多态之前我们先来看一下什么是虚函数, 虚函数 就是在基类中声明该函数是虚拟的(在函数之前加virtual关键字),然后在子类中正式的定义(子类中的该函数的函数名,返回值,函数参数个数,参数类型,全都与基类的所声明的虚函数相同,此时才能称为重写,才符合虚函数,否则就是函数的重载),再定义一个指向基类对象的指针,然后使该指针指向由该基类派生的子类对象,再然后用这个指针来调用改虚函数,就能实现动态多态。

下面我们通过一个例子来看一下利用虚函数实现的动态多态:

class A
{
public:
    A(int a = 10)
        :_a(a)
    {}
     virtual void Get()
    {
         cout << "A:: _a=" << _a << endl;
    }
public:
    int _a;
};

class B :  public A
{
public:
    B(int b = 20)
        :_b(b)
    {}
    void Get()
    {
        cout << "B:: _b=" << _b << endl;

    }

    int _b;
};

int main()
{
    A a1;
    B b1;
    A* ptr1 = &a1;
    ptr1->Get();

    ptr1 = &b1;
    ptr1->Get();

    return 0;
}

在这里我们看到,基类A的Get函数声明为虚函数,在B类中进行了重写,

然后在main函数中分别用基类的ptr1和指向子类的ptr2进行调用虚函数Get,我们得到了如下图的输出:

C++多态简析——静态多态与动态多态

这说明确实是实现了不同调用,而且是在运行时,那么虚函数的底层到底是怎么实现的呢,我们来看一下 汇编代码及其对象模型

C++多态简析——静态多态与动态多态

通过上图的汇编代码,我们看到这里做了一系列的指针解引用处理,最后确定了eax中应该存放的this指针的值,要搞清楚这个必须要搞清楚子类的对象模型。

C++多态简析——静态多态与动态多态

用监视窗口查看b1可以看到如上图所示,这里的_vfptr是一个虚表指针,它指向一个存放该类对象的所有虚函数的地址的表,我们可以将该表理解为一个函数指针数组,在该数组的最后一个元素,编译系统会将其置为0,。

对象模型如下图示:

C++多态简析——静态多态与动态多态

其中红色为A类的成员,黑色为B类对象b1的成员,紫色就是一个虚函数表,存放着存放该类对象的所有虚函数的地址,汇编代码做了一系列的指针解引用处理就是为了从虚函数表中找到相应的虚函数进行调用,从而实现了动态多态。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

产品型社群

产品型社群

李善友 / 机械工业出版社 / 2015-3-1 / CNY 69.00

传统模式企业正在直面一场空前的“降维战争”, 结局惨烈,或生或死。 传统模式很难避免悲惨下场, 诺基亚等昔日庞然大物轰然倒塌, 柯达发明了数码成像技术却依然破产, 新商业的兴起到底遵循的是什么模式? 微信轻而易举干掉了运营商的短信业务, “好未来”为何让传统教育不明觉厉? 花间堂为什么不是酒店,而是入口? 将来不会有互联网企业与传统企业之分, ......一起来看看 《产品型社群》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具