Fork me on GitHub

C++——多态实现原理分析

前言

虚函数执行速度要稍慢一些。为了实现多态性,每一个派生类中均要保存相应虚函数的入口地址表,函数的调用机制也是间接实现。所以多态性总是要付出一定代价,但通用性是一个更高的目标。

实验环境

Windows10 企业版

Visual Studio2017 15.8.1

引入虚函数后内存大小变

没有虚函数时类占用内存大小

#include<iostream>
using namespace std;

class Base
{
public:
    Base()
    {
        cout << "Create Base" << endl;
    }
     ~Base()
    {
        cout << "Free Base" << endl;
    }
public:
    void Show()
    {
        cout << "This is Base Show()" << endl;
    }
private:
    int x;
};

void main()
{
    cout << sizeof(Base) << endl;
    Base b;
}
View Code

占用内存为4字节。在x86 模式下,整形变量大小为4字节

有虚函数时类占用内存大小

#include<iostream>
using namespace std;

class Base
{
public:
    Base()
    {
        cout << "Create Base" << endl;
    }
     ~Base()
    {
        cout << "Free Base" << endl;
    }
public:
    virtual void Show()
    {
        cout << "This is Base Show()" << endl;
    }
private:
    int x;
};

void main()
{
    cout << sizeof(Base) << endl;
    Base b;
}
View Code

占用内存为8字节。在x86 模式下,整形变量大小为4字节。剩下4字节是虚函数表指针,指针变量在x86下占内存大小4字节。

代码中只定义了一个虚函数,定义多个虚函数,类的大小还是8。虚函数表的指针指向的是虚函数表的入口地址

虚函数表

 1 #include<iostream>
 2 using namespace std;
 3 
 4 class Base
 5 {
 6 public:
 7     Base()
 8     {
 9         cout << "Create Base" << endl;
10     }
11      ~Base()
12     {
13         cout << "Free Base" << endl;
14     }
15 public:
16     virtual void Show()
17     {
18         cout << "This is Base Show()" << endl;
19     }
20     virtual void Print()
21     {
22         cout << "This is Base Print()" << endl;
23     }
24     void Fun()
25     {
26         cout << "This is Base Fun()" << endl;
27     }
28 private:
29     int x;
30 };
31 
32 class D :public  Base
33 {
34 public:
35     D()
36     {}
37     ~D()
38     {}
39 public:
40     void Show()
41     {
42         cout << "This is D Show()" << endl;
43     }
44     void Fun()
45     {
46         cout << "This is D Fun()" << endl;
47     }
48     virtual void List()
49     {
50         cout << "This is D List()" << endl;
51     }
52 private:
53     int y;
54 };
55 
56 void main()
57 {
58     D d;
59 }
View Code

虚函数表前后变化

虚函数表在构造父类的时候会记录所有父类的虚函数

这里面少显示了子类的List虚方法,少显示是编译器的问题。但是你不能通过父类指针访问子类List()方法,因为List超出了父类范围。

子类构造完成后,子类重写了父类的虚函数,虚函数表中的虚函。数就变成了子类的。狸猫混太子,偷梁换柱的意思

 

posted @ 2018-08-28 23:43  克拉默与矩阵  阅读(218)  评论(0编辑  收藏  举报