使用函数指针模拟C++多态

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class Base
 5 {
 6 public :
 7     void display()
 8     {
 9         cout << "Base display" << endl;
10     }
11 
12     void (Base :: **VTable)();//指向虚表的函数指针
13     int a;
14 }; 
15 
16 class Derived : public Base
17 {
18 public :
19     void display()
20     {
21         cout << "derived display" << endl;
22     }
23 };
24 
25 void test(Base *pointer)
26 {
27     void (Base :: *pFunc)() = (void(Base :: *)())pointer->VTable[0];
28     (pointer->*pFunc)();
29 }
30 
31 int main()
32 {
33     //多态是通过多余的存储空间存储了虚函数的地址,通过函数指针来实现虚函数的调用
34     //1.分配空间+4,成员变量从+4的位置开始了。最上面的控件保留一个指针。
35     //2.为该指针指向的地址分配一块存储空间
36     //3.将所有虚函数的地址存储到这块存储空间中,这个存储空间称为虚表

    //初始化工作,也就是编译器帮我们做的事 37 Derived *derived = new Derived(); 38 derived->VTable = (void(Base :: **)())new int[1]; 39 derived->VTable[0] =(void(Base :: *)()) &Derived :: display;//初始化工作 40 test(derived); 41 42 Base *base = new Base(); 43 base->VTable = (void(Base :: **)())new int[1]; 44 base->VTable[0] = (void(Base :: *)()) &Base :: display; 45 test(base);
48 system("pause"); 49 return 0; 50 }

 基类如果不使用虚函数virtual构成多态的话,使用sizeof得到Base的大小为4,如下图(Base中的成员变量只有一个int a,使用32位编译器,如下代码中的基类,只是演示使用)

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class Base
 5 {
 6 public :
 7     void display()
 8     {
 9         cout << "Base display" << endl;
10     }
11 
12     int a;
13 }; 
14 
15 class Derived : public Base
16 {
17 public :
18     void display()
19     {
20         cout << "derived display" << endl;
21     }
22 };
23 
24 int main()
25 {
26     cout << "Base's size is " << sizeof(Base) << endl;
27     system("pause");
28     return 0;
29 }

如果使用virtual构成虚函数,再使用sizeof测试基类的大小,会发现基类大小增加了4

#include <iostream>
using namespace std;

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

    int a;
}; 

class Derived : public Base
{
public :
    void display()
    {
        cout << "derived display" << endl;
    }
};

int main()
{
    cout << "Base's size is " << sizeof(Base) << endl;
    system("pause");
    return 0;
}

 

那这个 4byte的空间是什么东西?是干什么用?

经过向父类加入多个虚函数,测试之后发现还是只是增加4byte,那么只有指针可以做到。

这个指针是一个二级指针,指向一个虚表的地址,虚表中存储的是父类与子类同名函数的地址。(比较复杂,我也只能理解到这个地步,所以表达更是low)

/**********************************************************************************2017/7/20,以后有了更深的理解再继续更新******************************************************************************************/

原文地址:https://www.cnblogs.com/SimonKly/p/7209910.html