zoukankan      html  css  js  c++  java
  • C++ 多态分析

    实验环境:Windows 10 + VS 2013

    通过虚函数可以实现多态,代码如下:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 class A {
     5 public:
     6     virtual void display() {
     7         cout << "This is A" << endl;
     8     }
     9     virtual void display2() {
    10         cout << "This is A2" << endl;
    11     }
    12 
    13 private:
    14     int _x;
    15 };
    16 
    17 class B : public A {
    18 public:
    19     virtual void display() {
    20         cout << "This is B" << endl;
    21     }
    22     virtual void display2() {
    23         cout << "This is B2" << endl;
    24     }
    25 
    26 private:
    27     int _y;
    28 };
    29 
    30 void display(A& a) {
    31     a.display();
    32     a.display2();
    33 }
    34 
    35 int main(int argc, char** argv) {
    36 
    37     A a;
    38     B b;
    39 
    40     display(a);
    41     display(b);
    42 
    43     return 0;
    44 }

    程序运行结果:

    分析第40行和41行代内部执行过程:

    main函数的汇编代码如下:

     其中 ebp-0x10 是 a 的地址, ebp-0x24 是 b 的地址。可以看到 a 和 b 调用display的代码一样,但是调用 display 前都将自己的地址(也是this指针)存到了eax寄存器,然后作为参数压入stack中。跳到display函数中看看:

     

    从上面图中可以看出,在非成员函数的display里面调用了成员函数display和display2。调用方式是通过虚表指针来调用的。this指针指向的是虚表指针,通过虚表指针找到虚函数表,然后再调用真正的display。

    因为子类和父类的虚函数表不同,所以不同类型的的class的虚表指针指向不同虚函数表。所以即使非成员函数display的参数是一个A类型(父类)的引用,但是B(子类)在调用时也能正确的执行想要的操作。

  • 相关阅读:
    清除浮动的几种方式
    css 居中问题总结
    Python 数据库Insert语句脚本生成工具(SQL Server)
    Windows安装运行Kafka
    C# 阿里云视频点播--视频转码
    C# 阿里云视频点播
    C# Assembly.LoadFile [A] 无法强制转换为 [B]
    OssFtp 用法
    C# Aspose.Words 用法
    C# 企业微信消息推送对接
  • 原文地址:https://www.cnblogs.com/triangleowl/p/12776206.html
Copyright © 2011-2022 走看看