• 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(子类)在调用时也能正确的执行想要的操作。

  • 相关阅读:
    【面积并】 Atlantis
    【动态前k大 贪心】 Gone Fishing
    【复杂枚举】 library
    【双端队列bfs 网格图建图】拯救大兵瑞恩
    【奇偶传递关系 边带权】 奇偶游戏
    【权值并查集】 supermarket
    CF w4d3 A. Pythagorean Theorem II
    CF w4d2 C. Purification
    CF w4d2 B. Road Construction
    CF w4d2 A. Cakeminator
  • 原文地址:https://www.cnblogs.com/triangleowl/p/12776206.html
Copyright © 2020-2023  润新知