C++ 对象模型 | 关于对象

一、C++ 对象模型

1、对象内存布局

在C++中,有两种数据成员:staticnonstatic,以及三种成员方法staticnonstaticvirtual,下面从虚函数、非虚函数、静态成员变量、非静态成员变量等维度来分析,类对象的内存布局。例如:下面定义一个Point类,包含前面四种类型的成员

#include <iostream>
using namespace std;class Point
{
public:Point(double val);virtual ~Point();         // virtual function numbersdouble GetPoint();        // notstatic function numbersstatic int PointCount();  // static function numbers
private:double m_x;           // notstatic data numbersstatic int m_count;   // static data numbers
};int Point::m_count = 0;Point::Point(double val):m_x(val) {}
Point::~Point() {}
double Point::GetPoint(){ return m_x; }
int Point::PointCount(){ return m_count; }int main()
{Point pt(10.0);cout << sizeof(pt) << endl;  // 输出结果:16return 0;
}

一个实例对象中包含非静态数据成员虚表指针以及为对齐而必需的填充静态成员变量函数独立于单个实例化对象。

总结:影响C++对象大小的三个因素:非静态数据成员虚函数字节对齐

2、空对象

C++规定空类对象大小至少为1字节,只是为了区分实例化对象。如果创建了多个空类的对象,可以通过对象的内存地址区分。例如:下面创建一个空类Empty

#include <iostream>
using namespace std;class Empty
{
};int main()
{Empty e;cout << sizeof(e) << endl;  // 输出结果:1return 0;
}

3、数据成员的声明顺序与内存布局

3.1、声明顺序与内存布局

同一访问级别非静态数据成员声明顺序与内存中的布局是一致的(即:先声明的非静态数据成员,先分配内存地址)。不同访问控制级别的非静态数据成员,未规定内存分配顺序,但是实际上,编译是按照声明顺序来安排内存,例如:定义一个Point3d类,并打印出成员地址

#include <iostream>
using namespace std;class Point3D
{
public:void Print() const {cout << "this addr " << this << endl;cout << "m_x addr " << &m_x << endl;cout << "m_y addr " << &m_y << endl;cout << "m_z addr " << &m_z << endl;}private:int m_x;int m_y;int m_z;
};int main()
{Point3D obj;obj.Print();return 0;
}

输出结果

this addr 0x61fe14
m_x addr 0x61fe14
m_y addr 0x61fe18
m_z addr 0x61fe1cProcess returned 0 (0x0)   execution time : 0.241 s
Press any key to continue.

3.2、声明顺序对内存的影响

字节对齐要求,对不同大小字节的非静态数据成员的声明顺序有什么启发?例如:分别定义Point3DPoint3D_Extend类,两个类具有相关的非静态数据成员,但是声明顺序不一样,两个类对象占用的内存大小也不一样

#include <iostream>
using namespace std;class Point3D
{
private:int m_x;short m_w;int m_y;short m_v;
};class Point3D_Extend
{
private:int m_x;int m_y;short m_w;short m_v;
};int main()
{Point3D obj1;Point3D_Extend obj2;cout << "Point3D object size: " << sizeof(obj1) << endl;cout << "Point3D_Extend object size: " <<sizeof(obj2) << endl;return 0;
}

输出结果:

Point3D object size: 16
Point3D_Extend object size: 12Process returned 0 (0x0)   execution time : 0.241 s
Press any key to continue.

结论:相同大小的非静态数据成员放在一起,可以减少一个类对象内存占用

4、继承下的内存布局(非多态)

4.1、单继承内存布局

当把一个大的object赋值给小的object时,会引起object的切割,将大object的subobject赋值给小的object。C++保证出现在derived class中的base class subobject有其完整原样性(即:派生类对象中有一个完整的基类对象)。例如:分别定义Point2dPoint3d

#include <iostream>
using namespace std;class Point2D
{
protected:int m_x;short m_y;
};class Point3D : public Point2D
{
private:short m_z;
};int main()
{Point2D *p1, *p2;p1 = new Point2D;p2 = new Point3D;*p1 = *p2;  // 大的对象赋值给小的对象时,会引起对象的切割return 0;
}

4.2、多继承与多重继承的对象布局

多继承场景内存布局同单继承场景类似,如下:

在这里插入图片描述

5、继承下的内存布局(多态)

如果类中声明了虚函数,会给类对象创建一个虚函数指针,指向虚函数表。基类与派生类都有自己的虚函数指针、如果派生类不实现基类的虚函数,派生类的虚函数表相同索引位置存储的是基类的虚函数指针。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/622538.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多线程(1)

1.实现多线程 1.1简单了解多线程【理解】 是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多个线程&#xff0c;提升性能。 1.2并发和并行【理解】 并行&#xff1a;在同一时刻&#xff0c;有多个指令在多个CPU上…

【打卡】牛客网:BM87 合并两个有序的数组

思想&#xff1a; 简单粗暴的方法是先合并、再排序。没有技术含量。 此外&#xff0c;很容易想到是用归并方法。问题是对A[]从前往后赋值&#xff0c;会覆盖A[]中有用的数值。 模板的巧妙之处是&#xff0c;从后往前赋值&#xff0c;完美避开覆盖问题。 我看了模板的之后写…

js let和var的区别

在JavaScript中&#xff0c;let和var都是用来声明变量的关键字&#xff0c;但它们之间存在一些重要的区别&#xff1a; 作用域&#xff1a;var声明的变量具有函数作用域或全局作用域&#xff0c;这意味着它们的作用域范围在函数内或全局范围内。相比之下&#xff0c;let声明的…

Centos创建一个Python虚拟环境

在 CentOS 上创建一个 Python 虚拟环境&#xff0c;可以使用 virtualenv 工具。以下是创建和激活虚拟环境的基本步骤&#xff1a; 1.安装virtualenv 如果还没有安装 virtualenv&#xff0c;可以使用以下命令安装&#xff1a; sudo yum install python3-virtualenv请注意&…

聚道云软件连接器助力知名企业,提升合同管理效率

一、客户介绍 某服饰股份有限公司是一家集服装设计、生产、销售及品牌建设于一体的企业。该公司的产品线涵盖男装、女装、童装等多个领域&#xff0c;设计风格时尚、简约、大方&#xff0c;深受消费者喜爱。公司注重产品研发&#xff0c;不断推陈出新&#xff0c;紧跟时尚潮流…

【linux笔记】vim

【linux笔记】vim 启动和退出 启动 vi退出 q强制退出 q&#xff01;编辑模式 vi foo.txt创建一个文件&#xff0c;启动后&#xff0c;是命令模式&#xff0c;是不能编辑的&#xff0c;键盘上的按键对应不同的命令。 插入模式 按键盘上的i&#xff0c;进入插入模式 保…

Redis(概述、应用场景、线程模式、数据持久化、数据一致、事务、集群、哨兵、key过期策略、缓存穿透、击穿、雪崩)

目录 Redis概述 应用场景 Redis的线程模式 数据持久化 1.Rdb&#xff08;Redis DataBase&#xff09; 2.Aof&#xff08;Append Only File&#xff09; mysql与redis保持数据一致 redis事务 主从复制&#xff08;Redis集群) 哨兵模式 key过期策略 缓存穿透、击穿、…

剑指offer面试题5 从尾到头打印链表

考察点 链表知识点 数组和链表都属于线性表。线性表在计算机中有俩种存储方式&#xff0c;按照顺序存储的就是数组&#xff0c;按照链式存储的就是链表&#xff0c;二者最大的区别在于一个是顺序存储(地址空间连续)一个是链式存储(地址空间不连续)。因此数组元素只包含元素值…

iToF wiggling校正技术

iToF技术中,wiggling是一种校正处理方法。在iToF模组获取深度图后,会进行一系列的补偿和校正处理,wiggling校正就是其中之一。这样的校正处理有助于最终获得更准确的3D数据。 wiggling校正技术有哪些应用场景 wiggling校正技术主要应用在间接飞行时间测量(iToF)装置中,…

【大厂秘籍】 - Java多线程面试题

Java多线程面试题 友情提示&#xff0c;看完此文&#xff0c;在Java多线程这块&#xff0c;基本上可以吊打面试官了 线程和进程的区别 进程是资源分配的最小单位&#xff0c;线程是CPU调度的最小单位 线程是进程的子集&#xff0c;一个进程可以有很多线程&#xff0c;每条线…

分享八个常用的 JavaScript 库

今天给大家分享8个常用的 JavaScript 库&#xff0c;掌握这些 JavaScript 工具库&#xff0c;让你的项目看起来很棒。 专家与普通人的重要区别在于他们善于使用工具&#xff0c;留出更多的时间用于计划和思考。编写代码也是如此。有了合适的工具&#xff0c;你就有更多的时间来…

UDS 诊断通讯

UDS有哪些车型支持 UDS(统一诊断服务)协议被广泛应用于汽车行业中,支持多种车型。具体来说,UDS协议被用于汽车电子控制单元(ECU)之间的通讯,以实现故障诊断、标定、编程和监控等功能。 支持UDS协议的车型包括但不限于以下几种: 奥迪(Audi)车型:包括A3、A4、A5、A6…

239.【2023年华为OD机试真题(C卷)】求幸存者之和(模拟跳数-JavaPythonC++JS实现)

🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目-求幸存数之和二.解题思路三.题解代码Python题解…

剑指offer题解合集——Week3day7

文章目录 剑指offerWeek3周七&#xff1a;分行从上往下打印二叉树AC代码思路&#xff1a; 周日&#xff1a;之字形打印二叉树AC代码思路&#xff1a; 剑指offerWeek3 周七&#xff1a;分行从上往下打印二叉树 题目链接&#xff1a;分行从上往下打印二叉树 从上到下按层打印…

JDK8终将走进历史,Oracle宣布JDK继续免费

目录 前言Oracle 已免费提供 JDKOracle Java SE 产品最新动态 为什么业界中用JDK8那么多Java SE 8 公共更新结束总结 前言 今天想到上个月无意中听闻到的一句话&#xff1a;JDK8之后收费了&#xff0c;所以大家都用JDK8。当时只觉得这个话说得不对&#xff0c;但因为和说话的人…

Django数据库选移的preserve_default=False是什么意思?

有下面的迁移命令&#xff1a; migrations.AddField(model_namemovie,namemov_group,fieldmodels.CharField(defaultdjango.utils.timezone.now, max_length30),preserve_defaultFalse,),迁移命令中的preserve_defaultFalse是什么意思呢&#xff1f; 答&#xff1a;如果模型定…

点击随机红点的简单游戏(pygame)

import pygame import sys import random# 初始化 Pygame pygame.init()# 设置窗口大小 width, height 800, 600 screen pygame.display.set_mode((width, height)) pygame.display.set_caption("Click the Red Dot")# 定义颜色 black (0, 0, 0) red (255, 0, 0)…

Apache POI 导出Excel报表

大家好我是苏麟 , 今天聊聊Apache POI . Apache POI 介绍 Apache POI 是一个处理Miscrosoft Office各种文件格式的开源项目。简单来说就是&#xff0c;我们可以使用 POI 在 Java 程序中对Miscrosoft Office各种文件进行读写操作。 一般情况下&#xff0c;POI 都是用于操作 E…

浅谈 Raft 分布式一致性协议|图解 Raft

前言 大家好&#xff0c;这里是白泽。本文是一年多前参加字节训练营针对 Raft 自我整理的笔记。 本篇文章将模拟一个KV数据读写服务&#xff0c;从提供单一节点读写服务&#xff0c;到结合分布式一致性协议&#xff08;Raft&#xff09;后&#xff0c;逐步扩展为一个分布式的…

2024年华为OD机试真题-手机App防沉迷系统-Java-OD统一考试(C卷)

题目描述&#xff1a; 智能手机方便了我们生活的同时&#xff0c;也侵占了我们不少的时间。“手机App防沉迷系统”能够让我们每天合理的规划手机App使用时间&#xff0c;在正确的时间做正确的事。 它的大概原理是这样的&#xff1a; 1、在一天24小时内&#xff0c;可注册每个Ap…