• 【C++】 对象模型与内存模型的区别


    请添加图片描述

    • 🙋‍♂️ 作者:海码007
    • 📜 专栏:C++专栏
    • 💥 标题:【C++】 对象模型与内存模型的区别
    • ❣️ 寄语:最重要的只有一件事!
    • 🎈 最后:文章作者技术和水平有限,如果文中出现错误,希望大家能指正

    0 引言

    闲聊:❣️随着学习的深入,总是会涉及到内存模型和对象模型。最开始接触这两个概念的时候总是觉得很抽象,什么是模型,三维模型?,显然不是。下面就来学习一下这两个概念❣️

    1 C++ 内存模型

    C++内存模型描述了C++程序如何在内存中分配和管理内存。它包括栈、堆以及全局/静态存储区等不同的内存区域。

    C++内存分区有很多种,从不同的角度可以划分成不同的分区模块,下面就讲述一下通常情况下的分区:

    • 栈(Stack)
      栈是用于存储局部变量函数调用信息的内存区域。
      它在程序运行时动态地增长和收缩。每当函数被调用时,该函数的局部变量和返回地址等信息都会被压入栈中。当函数执行结束后,这些信息会从栈中弹出。栈的分配和释放是由编译器自动管理的,因此栈上的内存是自动分配和释放的,具有较快的分配和释放速度,但大小受到限制。
    • 堆(Heap)
      堆是用于动态分配内存的内存区域。
      它的大小通常比栈大得多,并且可以在程序运行时根据需要动态地分配和释放内存。在堆上分配的内存通过调用new运算符或malloc函数来实现,并且需要手动释放,否则会导致内存泄漏。堆上的内存可以被多个部分共享,并且需要程序员显式地管理。
    • 全局/静态存储区(Global/Static Storage)
      全局存储区用于存储全局变量和静态变量,它在程序的整个生命周期内都存在
      全局变量是在程序开始时就被初始化的,而静态变量则在第一次使用时初始化,并且在程序的整个执行过程中保持其值不变。全局/静态存储区的内存由编译器分配和释放。
    • 常量存储区(Constant Storage)
      常量存储区用于存储常量值,如字符串常量
      这些常量值在程序的整个执行过程中保持不变。常量存储区的内存由编译器分配和释放。
    • 程序代码区(Code Segment)
      程序代码区存储程序的执行代码
      这些代码在程序运行期间是只读的,不可修改。代码区的内存由操作系统加载和管理。

    2 C++ 对象模型

    在C++对象模型中,一个类的对象通常由成员变量和成员函数组成。成员变量存储对象的状态信息,而成员函数定义了对象的行为。对象的成员变量在内存中按照声明的顺序依次存储,成员函数则是共享的,不会为每个对象创建一份副本。

    C++的对象模型还包括对继承关系的支持。当一个类继承自其他类时,它会继承父类的成员变量和成员函数,并可能添加自己的新成员。继承关系在内存中通常通过在对象布局中添加额外的内存来实现。

    在C++对象模型中,变量、成员函数和虚函数的组织方式如下

    • 变量的组织
      非静态成员变量,它们按照声明的顺序依次存储在对象的内存中。每个对象都有自己的成员变量副本
      静态成员变量 在类的所有对象之间共享,它们存储在类的静态数据区中,而不是对象的内存中。
    • 成员函数的组织
      非静态成员函数不会存储在对象的内存中。它们被视为类的共享函数,可以在所有对象之间共享
      非静态成员函数通过一个隐藏的额外参数(this指针)来访问调用它们的对象的成员变量
      成员函数的指针存储在类的函数表(也称为虚函数表)中。函数表是一个指针数组,其中每个指针指向相应的成员函数。
    • 虚函数的组织
      虚函数是用于实现多态性特殊类型的成员函数
      类中声明为虚函数的函数被放入虚函数表中。
      每个对象都包含一个指向虚函数表的指针(通常称为虚函数表指针),该指针指向类的虚函数表。
      当通过基类指针或引用调用虚函数时,会根据对象的实际类型在虚函数表中查找相应的函数,并进行动态绑定

    3 二者区别

    • C++对象模型和内存模型的主要区别在于它们关注的方面不同
      对象模型关注的是类和对象的组织方式,包括成员变量和成员函数的布局,以及继承关系的处理。
      内存模型关注的是程序运行时内存的分配和管理,包括栈、堆和全局/静态存储区的使用。
    • 对象模型是一种高级的概念,描述了C++语言中类和对象的结构和行为。它帮助我们理解和使用面向对象编程的特性,如封装、继承和多态。
    • 内存模型则更加底层,描述了C++程序在运行时如何使用内存。它涉及到内存的分配和释放,以及变量的作用域和生命周期等方面。
  • 相关阅读:
    专业综合课程设计 - 优阅书城项目(第一版)
    Layui基础
    Java学习Day031(异常)
    python 安装环境 初版
    Android入门第39天-系统设置Configuration类
    nodejs+vue菜谱美食食谱网站系统
    用《斗破苍穹》的视角打开C#委托2 委托链 / 泛型委托 / GetInvocationList
    一种基于光强传输方程的散射成像相位恢复仿真研究
    【Linux】提升Linux命令行效率:光标移动和文本操作的键盘快捷键
    【Spring高级】第3讲 Bean的生命周期
  • 原文地址:https://blog.csdn.net/hhw_hhw/article/details/133658750