【C++】类和对象的关系,对象的存储方式以及对象内存的计算

在这里插入图片描述

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤
📃个人主页 :阿然成长日记 👈点击可跳转
📆 个人专栏: 🔹数据结构与算法🔹C语言进阶
🚩 不能则学,不知则问,耻于问人,决无长进
🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍

文章目录

  • 一、 类和对象的关系
  • 二、类在内存中的存储方式
    • 1.类的构成
    • 2.内存分布
    • 3.分析存储方式
  • 三、类对象大小的计算
    • 1.案例引入
    • 2.计算方法:
    • 3.分析下面案例:
    • 4.空类大小的计算
  • 补充:

一、 类和对象的关系

  • :类是一个抽象概念,是一类具有相同特征的事物的统称,不是具体存在的,
  • 对象:对象是一种具体概念,对象是具体事物的实体。

类和对象的关系:简单来说类是抽象的,不占用内存,而对象是具体的,占用存储空间。类->对象【一对多的关系】。一个类的实例化就是一个对象的创建。
举一个例子:大学生是一个类,那么大学生小明就是其中的一个对象大学生张三也是一个对象。
在这里插入图片描述

二、类在内存中的存储方式

1.类的构成

首先,一个类分为两个部分,成员变量+成员函数
在这里插入图片描述

2.内存分布

对于成员变量来说,我们每次创建一个对象,肯定是要给他初始化不同的值(如果传相同的值,有啥意义呢),那么,成员变量是一定要进行另外的存储的。对于成员函数来说,我们使用的是同一个函数,用实现同一个操作,就没有必要在对象中额外拷贝一份函数存储到内存中来,所以,对象想要使用类中的函数直接去调用公共代码区的函数就可以了。
例如:就好比说一个小区,睡觉的时候你肯定要有自己的床,每个人都会有自己的小床,但是打篮球的时候就没有必要建立自己的篮球场,大家可以共同使用同一个篮球场。也就是说对于成员函数的存储我们在对象中只需要保存它的一份地址,直接调用即可。
用图来表示:
在这里插入图片描述

3.分析存储方式

上图就是类实例化的对象在内存中的分布情况,其中值得注意的是成员函数并不存储于每个对象中,而是多个对象共享函数代码,函数存在于公共内存中,由一个函数表统一管理,函数表中存储着每个函数的地址。当我们在对象中去调用函数时,通过类中的一个指针,找到函数表,在从中找到对应的地址,从而进行调用。
注意点:内联函数(也就是函数的定义和声明都在类中)调用时效率很高,因为它在编译时就已经在原位置进行替换,不需要在函数表中去查找调用。所以,这也就是我们为什么提倡把一些简短的,调用频繁的函数声明为inline(内联函数)。

三、类对象大小的计算

1.案例引入

例如:如下代码

class Data
{
public:
	void Print()
	{
		cout << _year << _month << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

这个给Data类的大小计算结果是12.那我们可以想一下为什么是12而不是别的,类的大小是怎么计算的,带着这个问题我们向下学习-><-

2.计算方法:

通过上面类对象在内存中的存储的学习,我们知道:

  • 类本身不占用内存,实例化出的对象 ,占用实际的物理空间。
  • 成员变量存在对象中
  • 成员函数的地址不在对象中。

类的大小计算 == 结构体内存对齐

如果你忘记了结构体大小,请看我的这篇博客:结构体内存对齐

3.分析下面案例:

例如:计算下面类的大小

#include<iostream>
using namespace std;
class Data
{
public:
	void Init(int year,int month,int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Data d1;
	cout << sizeof(Data) << endl;
}

运行结果
在这里插入图片描述

上面代码类对象的大小计算,只需要看成员变量那一块地方。为了减小内存的开支,我们需要合理安排类成员变量的先后顺序。

4.空类大小的计算

class T
{

};
int main()
{
	cout << sizeof(T) << endl;
}

在这里插入图片描述

无成员变量的类(里面可能有成员函数),对象开一个字节,因为空类可以实例化,实例化必然在内存中占有一个位置,因此,编译器为其优化为一个字节大小。

补充:

由于还没有学习虚函数,继承等等,对象的大小的计算不是很完整,等下来学习了之后,在做整理!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Window10安装Docker

文章目录 Window10安装Docker前提条件Hyper -VWSL 2.0 安装包下载执行安装包更新 Window10安装Docker 前提条件 Hyper -V 如何启用 WSL 2.0 安装包下载 官网地址 下载后&#xff1a; 执行安装包 wsl --update等得有点久 重新打开 拉取一个helloworld镜像 说明已经…

【CocosCreator】利用遮罩Mask实现单边开门效果

如果对前端八股文感兴趣&#xff0c;可以留意公重号&#xff1a;码农补给站&#xff0c;总有你要的干货。 实现思路 首先新建一个新的遮罩节点&#xff08;全部采用默认属性&#xff09;&#xff0c;将其大小设为门的大小&#xff0c;然后将其摆放到门所在的位置&#xff0c;如…

MATLAB_5MW风电永磁直驱发电机-1200V直流并网MATLAB仿真模型

仿真软件&#xff1a;matlab2016b 风机传动模块、PMSG模块、蓄电池模块、超级电容模块、无穷大电源、蓄电池控制、风机控制、逆变器控制等模块。 逆变器输出电压&#xff1a; 混合储能系统SOC&#xff1a; 威♥关注“电击小子程高兴的MATLAB小屋”获取更多精彩资料&#xff0…

单调栈【2023年最新】

做题的时候看到了单调栈&#xff0c;但是不知道是个什么玩意&#xff0c;记录一下吧。 单调栈含义 单调栈是一种特殊的数据结构&#xff0c;用于解决一些与单调性相关的问题。它的基本含义是在栈的基础上&#xff0c;维护一个单调递增或单调递减的栈。 在单调递增栈中&#…

SpringCloud-Gateway无法使用Feign服务(2021.X版本)

Spring Cloud Gateway 2021.x版本&#xff0c;无法使用Feign调用其他服务接口。 问题原因&#xff1a; 在官网的 issue 里面找到了相关的问题。 How to call another micro-service on GatewayFilterFactory ? Issue #1090 spring-cloud/spring-cloud-gateway GitHubHel…

QT QSplitter

分裂器QSplitter类提供了一个分裂器部件。和QBoxLayout类似&#xff0c;可以完成布局管理器的功能,但是包含在它里面的部件,默认是可以随着分裂器的大小变化而变化的。 比如一个按钮放在布局管理器中,它的垂直方向默认是不会被拉伸的,但是放到分裂器中就可以被拉伸。还有一点不…

OV5640的参数与配置方法

分辨率和速率&#xff08;FPS&#xff09; 寄存器配置 I/O 板的驱动能力和方向控制 system clock control OV5640 PLL 允许输入时钟频率范围为 6~27 MHz&#xff0c;最大 VCO 频率为 800 MHz。 MipiClk 用于 MIPI&#xff0c;SysClk 用于图像信号处理 (ISP) 模块的内部时钟。 …

TensorFlow(1):深度学习的介绍

1 深度学习与机器学习的区别 学习目标&#xff1a;知道深度学习与机器学习的区别 区别&#xff1a;深度学习没有特征提取 1.1 特征提取方面 机器学习的特征工程步骤是要靠手动完成的&#xff0c;而且需要大量领域专业知识深度学习通常由多个层组成&#xff0c;它们通常将更简…

Redis系列之实现分布式自增主键

软件环境 JDK 1.8 SpringBoot 2.2.1 Maven 3.2 Mysql 8.0.26 redis 6.2.14 Mybatis Plus 3.4.3.4 开发工具 IntelliJ IDEA smartGit 一、实现原理 使用Redis来实现分布式的主键自增主要是依赖于Redis的INCR命令&#xff0c;调用INCR命令的对应key&#xff0c;其数值…

centos7部署Canal与Canal集成使用

1、简介 canal [kə’nl]&#xff0c;译意为水道/管道/沟渠&#xff0c;主要用途是基于 MySQL 数据库增量日志解析&#xff0c;提供增量数据订阅和消费 早期阿里巴巴因为杭州和美国双机房部署&#xff0c;存在跨机房同步的业务需求&#xff0c;实现方式主要是基于业务 trigge…

Flink架构

1、Apache Flink集群的核心架构&#xff1a; 1、client&#xff08;作业客户端&#xff09;&#xff1a;提交任务的地方叫做客户端 2、JobManager&#xff08;作业管理器&#xff09;&#xff1a;作用是用于管理集群中任务 3、TaskManager&#xff08;任务管理器&#xff09;&a…

k8s 1.28安装

容器运行时&#xff0c;containerd 按照官方的指导&#xff0c;需要安装runc和cni插件&#xff0c;提示的安装方式&#xff0c;有三种&#xff1a; 二进制安装包源码apt-get 或 dnf安装 我们这里选用第三种&#xff0c;找到docker官方提供的安装方式 ubuntu-containerd # A…

Elasticsearch:使用你的 RAG 来进行聊天

什么是人工智能中的检索增强生成&#xff08;RAG&#xff09;&#xff1f; 检索增强生成 (RAG)&#xff0c;与你的文档聊天的超级英雄&#xff0c;架起信息检索和文本生成世界的桥梁&#xff01; 这就像福尔摩斯和莎士比亚联手解决需要大量知识的复杂任务。 RAG 突然介入&…

网络编程套接字(3)——协议定制 | 序列化与反序列化

文章目录 一.认识“协议”1.协议的概念2.结构化数据的传输3.序列化和反序列化 二. 网络版计算器1.服务端2.协议定制(1) 网络发送和读取的正确理解(2) 协议定制的问题 3.客户端4.代码 三.Json实现序列化反序列化1.简单介绍2.使用 一.认识“协议” 1.协议的概念 协议&#xff0c…

Pytest插件

官方文档&#xff1a;API Reference — pytest documentation BaseReport 定义Case结果输出 >>> from _pytest.reports import TestReport >>> test TestReport(1,1,1,pass,,running) >>> print(dir(test)) [__annotations__, __class__, __delatt…

02-MySQL-基础-增删改查

一、DDL 定义数据库对象&#xff08;数据库&#xff0c;表&#xff0c;字段&#xff09; ①&#xff1a;数据库操作 01. 查询 1. 查询所有数据库 show databases;2. 查询当前使用的数据库 SELECT database();02. 使用 USE sys;03. 创建 CREATE DATABASE [IF NOT EXISTS]数据…

自动化测试(Java+eclipse)教程

webdriver环境配置 1.下载chromedriver到本地&#xff08;一定要选择和自己浏览器相对应的版本chromedriver下载地址&#xff09; 2.加入到环境变量path中 webdriver工作原理 创建web自动化测试脚本 1.Maven项目创建 File->New->project->(搜索maven)选择maven pr…

JavaScript客户端操作

BOM(browser object model)是浏览器对象模型的简称&#xff0c;被广泛应用于Web开发中&#xff0c;主要用于对客户端浏览器的管理。BOM的概念比较古老&#xff0c;但是一直没有被标准化&#xff0c;不过各主流浏览器均支持BOM&#xff0c;都遵守最基本的规则和用法&#xff0c;…

Dcoker学习笔记(一)

Dcoker学习笔记一 一、 初识Docker1.1 简介1.2 虚拟机和docker的区别1.3 Docker架构1.4 安装Docker&#xff08;Linux&#xff09; 二、 Dcoker基本操作2.1 镜像操作2.2 容器操作练习 2.3 数据卷volume&#xff08;容器数据管理&#xff09;简介数据卷语法数据卷挂载 2.4 自定义…

【Node.js入门】1.1Node.js 简介

Node.js入门之—1.1Node.js 简介 文章目录 Node.js入门之—1.1Node.js 简介什么是 Node.js错误说法 Node.js 的特点跨平台三方类库自带http服务器非阻塞I/O事件驱动单线程 Node.js 的应用场合适合用Node.js的场合不适合用Node.js的场合弥补Node.js不足的解决方案 什么是 Node.j…