• 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超出了父类范围。

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

  • 相关阅读:
    类别category 总结
    autorelease理解
    NSAutoreleasePool drain release的区别
    ios 文件管理 目录
    关于autorelease pool一个较好的理解
    iOS中四种实例变量的范围类型@private@protected@public@package
    批量删除
    会话用法 和留言板例题
    运用php做投票题,例题
    php 封装
  • 原文地址:https://www.cnblogs.com/kelamoyujuzhen/p/9551717.html
Copyright © 2020-2023  润新知