zoukankan      html  css  js  c++  java
  • [转] C++虚函数与虚函数表

    http://www.cnblogs.com/Ripper-Y/archive/2012/05/15/2501930.html

    http://blog.csdn.net/haoel/article/details/1948051/

    多态性可分为两类:静态多态和动态多态。函数重载和运算符重载实现的多态属于静态多态,动态多态性是通过虚函数实现的。

    每个含有虚函数的类有一张虚函数表(vtbl),表中每一项是一个虚函数的地址, 也就是说,虚函数表的每一项是一个虚函数的指针。

    没有虚函数的C++类,是不会有虚函数表的。

    两张图:

     class Base {
     public:
         virtual void f() { cout << "Base::f" << endl; }
         virtual void g() { cout << "Base::g" << endl; }
         virtual void h() { cout << "Base::h" << endl; }
     };

     class Derived : public Base
     {
     public:
         virtual void f() { cout << "Derived::f" << endl; }
     };

     typedef void(*Fun)(void);

     int main(int argc, char *argv[])
     {
         Base b;
         Derived d;
         Fun pFun = NULL;

         // Invoke the first virtual function
         // Base
         int **pVtab = reinterpret_cast<int **>(&b);
         pFun = reinterpret_cast<Fun>(pVtab[0][0]);
         (pFun) ();

    }

    安全性

     

    每次写C++的文章,总免不了要批判一下C++。这篇文章也不例外。通过上面的讲述,相信我们对虚函数表有一个比较细致的了解了。水可载舟,亦可覆舟。下面,让我们来看看我们可以用虚函数表来干点什么坏事吧。

     

    一、通过父类型的指针访问子类自己的虚函数

    我们知道,子类没有重载父类的虚函数是一件毫无意义的事情。因为多态也是要基于函数重载的。虽然在上面的图中我们可以看到Base1的虚表中有Derive的虚函数,但我们根本不可能使用下面的语句来调用子类的自有虚函数:

     

              Base1 *b1 = new Derive();

                b1->f1();  //编译出错

     

    任何妄图使用父类指针想调用子类中的未覆盖父类的成员函数的行为都会被编译器视为非法,所以,这样的程序根本无法编译通过。但在运行时,我们可以通过指针的方式访问虚函数表来达到违反C++语义的行为。(关于这方面的尝试,通过阅读后面附录的代码,相信你可以做到这一点)

     

    二、访问non-public的虚函数

    另外,如果父类的虚函数是private或是protected的,但这些非public的虚函数同样会存在于虚函数表中,所以,我们同样可以使用访问虚函数表的方式来访问这些non-public的虚函数,这是很容易做到的。

  • 相关阅读:
    HDU 4745 Two Rabbits (区间DP)
    HDU 1007 Quoit Design最近点对( 分治法)
    acdream 小晴天老师系列——我有一个数列! (ST算法)
    HDU 3592 World Exhibition (差分约束,spfa,水)
    HDU 5501 The Highest Mark (贪心+DP,经典)
    HDU 5500 Reorder the Books (水题)
    HYSBZ 1010 玩具装箱toy (决策单调DP)
    POJ 3017 Cut the Sequence (单调队列优化DP)
    Vijos P1243 生产产品 (单调队列优化DP)
    PIVOT&UNPIVOT
  • 原文地址:https://www.cnblogs.com/qiangxia/p/4284214.html
Copyright © 2011-2022 走看看