zoukankan      html  css  js  c++  java
  • C++虚函数原理及函数调用栈模型

      精简原文:http://blog.csdn.net/haoel/article/details/1948051/

      关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法。比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议。

      对C++ 了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表Virtual Table)来实现的。简称为V-Table。在这个表中,主是要一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证其容真实反应实际的函数。这样,在有虚函数的类的实例中这个表被分配在了这个实例的内存中,所以,当我们用父类的指针来操作一个子类的时候,这张虚函数表就显得由为重要了,它就像一个地图一样,指明了实际所应该调用的函数。

      1.Base中3个虚函数,Derive中3个虚函数:

      1)虚函数按照其声明顺序放于表中。

      2)父类的虚函数在子类的虚函数前面。

      2.Derive重载f()后:

      1)覆盖的f()函数被放到了虚表中原来父类虚函数的位置。

      2)没有被覆盖的函数依旧。

      3.多重继承后:

      1)  每个父类都有自己的虚表。

      2)  子类的成员函数被放到了第一个父类的表中。(所谓的第一个父类是按照声明顺序来判断的)

      4.函数调用栈模型

    具体来说,从内存的角度看,函数h调用f时,Stack是按下面步骤发生变化的:

    1. 实参按照从右向左的顺序一个一个进入stack中。
    2. 函数调用指令之后的“下一条指令地址”进入stack中。(pRetAddr)
    3. EBP(栈指针)指向调用此函数的函数栈地址。(FuncB's EBP)
    4. 函数f中的局部变量加入到stack中。
    5. 函数f中的局部变量从Stack中弹出。
    6. “下一条指令地址”从stack中弱出,流入程序计数器寄存器IP中。
    7. 寄存器AX/EAX/RAX中的值流入到stack中h的局部变量(或者全局变量等)中。(返回值)
    8. 调用函数f时的实参从stack中弹出。

     

  • 相关阅读:
    Android 动画-alpha(渐变透明度动画效果)
    Memento(备忘录)
    Mediator(中介者)
    Iterator(迭代器)
    Command(命令)
    Chain of Responsibility(责任链)
    Template Method(模板方法)
    Interpreter(解释器)
    Proxy(代理)
    Flyweight(享元)
  • 原文地址:https://www.cnblogs.com/jslee/p/3421429.html
Copyright © 2011-2022 走看看