IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 普通继承环境下的C++对象模型 -> 正文阅读

[C++知识库]普通继承环境下的C++对象模型

对象模型基础

C++在C的基础上引入了面向对象的程序设计思想,类的封装、继承和多态使得C++功能更加强大,C++的类包含数据成员和成员函数:
数据成员: 静态数据成员,非静态数据成员
成员函数: 非静态成员函数、静态函数、虚函数
C++对象模型研究C++类的数据成员和成员函数在内存中如何布局的问题:
例如:

class Base
{
public:
    int member;  // 非静态数据成员
    static int smember;  // 静态数据成员
    
    void func();  // 非静态成员函数
    static void sfunc();  // 静态成员函数
    virtual void vfunc();  // 虚函数
}
  • 简单对象模型

在简单对象模型中,类的每个实例化对象在内存中都会申请一块连续内存,在这块内存上保存着指向成员变量和函数的指针
如图所示:
在这里插入图片描述
优点: 每个对象的内存大小是固定的,不管是数据成员还是成员函数,都只对应一个指针,在访问时可以很快计算出指针偏移量
弊端: 当访问对象的数据成员时,需要先找到数据成员的指针,然后通过这个指针获取到真实的数据,多了一次寻址,效率较低

  • 表驱动对象模型
    表格驱动对象模型对类中的数据成员和成员函数进行了区分,每个对象保留两个指针,一个指向数据成员表,其中存放数据成员的取值,一个指向成员函数表,其中存放指向成员函数的指针
    如图:
    在这里插入图片描述
    优点: 对数据和函数进行分开管理
    弊端: 访问成员函数时,需要先找到成员函数表,效率更低

  • C++对象模型
    以Base类为例,C++对象模型如图所示:
    在这里插入图片描述
    可以看出:

  • C++对象模型中有一个指向虚函数表的指针,这个虚函数表中除了存放虚函数的指针之外,还有一个type_info的信息,用于在运行时识别对象的正确类型。

  • C++对象的非静态成员变量存放在对象的内存空间中,静态成员变量存放在全局数据区

  • C++对象的成员函数存放在代码区

普通继承场景下的对象模型

  • 单一继承场景
    以Base为基类,定义派生类Derived如下:
class Derived : public Base
{
public:
    int member;  // 非静态数据成员
    static int smember_d;  // 静态数据成员
    
    void func();  // 非静态成员函数
    static void sfunc_d();  // 静态成员函数
    virtual void vfunc();  // 虚函数
    virtual void vfunc_d();  // 虚函数
}

对象模型如下:
在这里插入图片描述
派生类有自己的虚函数表,从基类那边拷贝一份,然后进行修改:将type_info改为派生类的信息;如果派生类重写了基类的虚函数vfunc,那么虚函数表中用Derived::vfunc()的指针替换Base::vfunc()的指针;如果派生类新增了虚函数vfunc_d,那么虚函数表中新增一个函数指针指向Derived::vfunc_d()。

  • 多重继承场景
    单一继承场景下,派生类在基类的虚函数表上进行修改。多重继承场景,有多个基类的虚函数表。定义基类Base1和派生类Derived如下:
class Base1
{
public:
    int member1;  // 非静态数据成员
    
    virtual void vfunc();  // 虚函数
    virtual void vfunc1();  // 虚函数
    virtual void vfunc2();  // 虚函数
};

class Derived : public Base, public Base1
{
public:
    int member_d;  // 非静态数据成员
    static int smember_d;  // 静态数据成员
    
    void func();  // 非静态成员函数
    static void sfunc_d();  // 静态成员函数
    virtual void vfunc();  // 虚函数
    virtual void vfunc1();  // 虚函数
    virtual void vfunc_d();  // 虚函数
};

此时Derived的对象模型为:
在这里插入图片描述

继承多个父类时,派生类的对象模型中分别存储一个虚函数表的指针。如果派生类重写的基类同名虚函数,那就在虚函数表中进行替换;如果派生类新增了虚函数,那么在第一个父类的虚函数表中进行新增扩展。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-30 12:34:13  更:2021-07-30 12:34:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/3 1:11:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码