【C++】成员对象和成员函数分开存储

news2024/11/28 12:43:12

        欢迎来到博主 Apeiron 的博客,祝您旅程愉快 ! 时止则止,时行则行。动静不失其时,其道光明。


目录

1、缘起

2、详解

3、代码清单 1

3.1、类中定义成员变量

3.2、类中定义成员函数

4、代码清单 2

5、总结 


1、缘起

        “成员变量和成员函数分开存储” 是面向对象编程中的一个重要概念。它指的是在类的实例化过程中,类的 成员变量 成员函数 分别存储在不同的内存位置。

2、详解

        具体来说,当创建类的实例(对象)时,会为每个对象分配一块内存用于存储该对象的成员变量。这些成员变量是对象的属性,它们的值可以因对象而异。每个成员变量包含类定义中声明的实例变量,可以通过对象访问和操作。

        而成员函数则被存储在类的代码区域,它们是类的行为或操作的定义。成员函数被所有该类的对象所共享,它们可以操作对象的成员变量,并对对象进行各种操作和处理。这种将成员变量和成员函数分开存储的方式有以下几个优点:

①  内存分配的效率:成员变量被存储在各个对象的内存中,每个对象只需存储自己的成员变量,避免了重复存储相同的成员变量,节省了内存空间。

②  对象的独立性:每个对象都有自己的成员变量,它们的值可以相互独立,互不影响。这样可以实现对象的封装和数据隔离,增强了对象的独立性和安全性。

③  方法的共享性:所有对象共享类的成员函数,它们可以在不同的对象上执行相同的操作。这提供了代码的重用性和灵活性。

总的来说,将成员变量和成员函数分开存储有助于实现面向对象编程的封装、数据隔离和代码共享等特性,提高了程序的可维护性和可扩展性。

3、代码清单 1

3.1、类中定义成员变量

示例代码 1:定义一个空类

#include<iostream>
#include<string>

using namespace std;

class Person
{

};

void test()
{
	Person p;

	cout << "对象 p 所占的内存空间大小:" << sizeof(p) << endl;
}

int main()
{
	test();

	cout << endl;
	system("pause");
	return 0;
}

        从上述代码和结果图中可以看出,当定义一个空类时,C++ 编译器会给每个空对象也分配 1 个字节空间,是为了区分空对象占内存的位置,每个对象也应该有一个独一无二的内存地址。 

示例代码 2:类中定义一个非静态成员变量 

#include<iostream>
#include<string>

using namespace std;

class Person
{
	int p_age;
};

void test()
{
	Person p;

	cout << "对象 p 所占的内存空间大小:" << sizeof(p) << " 字节" << endl;
}

int main()
{
	test();

	cout << endl;
	system("pause");
	return 0;
}

        从上述代码和结果图中可以看出,当定义一个空类时,对象 p 占用 1 个字节的空间;当在这个空类中声明一个 非静态成员变量 (int p_age;) 时,对象 p 占用 4 个字节的空间。这是因为非静态成员变量时属于类的对象上,并且被存储在各个对象的内存中,而对象 p 占用空间的大小就是 int 数据类型的大小。

示例代码 3:类中定义两个非静态成员变量

示例代码 2 的对照组。

#include<iostream>
#include<string>

using namespace std;

class Person
{
	int p_age;
	int p_height;
};

void test()
{
	Person p;

	cout << "对象 p 所占的内存空间大小:" << sizeof(p) << " 字节" << endl;
}

int main()
{
	test();

	cout << endl;
	system("pause");
	return 0;
}

        从上述代码和图片中可以看出,当在类中声明两个非静态成员变量时,对象 p 占用 8 个字节内存空间。 

示例代码 4:类中定义一个静态成员变量

#include<iostream>
#include<string>

using namespace std;

class Person
{
	static int p_age;
};

void test()
{
	Person p;

	cout << "对象 p 所占的内存空间大小:" << sizeof(p) << " 字节" << endl;
}

int main()
{
	test();

	cout << endl;
	system("pause");
	return 0;
}

        从上述代码和结果图中可以看出,当在类中定义一个 静态成员变量 时,对象 p 占用 1 个内存空间,这和空类时对象 p 所占用的空间大小相等,这说明了静态成员变量不属于对象的成员,它是类的成员。 

示例代码 5:类中定义两个静态成员变量

示例代码 4 的对照组。

#include<iostream>
#include<string>

using namespace std;

class Person
{
	static int p_age;
	static int p_height;
};

void test()
{
	Person p;

	cout << "对象 p 所占的内存空间大小:" << sizeof(p) << " 字节" << endl;
}

int main()
{
	test();

	cout << endl;
	system("pause");
	return 0;
}

3.2、类中定义成员函数

示例代码 1:类中定义一个非静态函数 

#include<iostream>
#include<string>

using namespace std;

class Person
{
	void func() {};
};

void test()
{
	Person p;

	cout << "对象 p 所占的内存空间大小:" << sizeof(p) << " 字节" << endl;
}

int main()
{
	test();

	cout << endl;
	system("pause");
	return 0;
}

        从上述代码和结果图中可以看出,当在类中定义一个 非静态成员变量 时,对象 p 占用 1 个内存空间,这和空类时对象 p 所占用的空间大小相等,这说明了非静态成员函数不属于对象的成员,它是类的成员。  

示例代码 2:类中定义一个静态成员函数

#include<iostream>
#include<string>

using namespace std;

class Person
{
	static void func() {};
};

void test()
{
	Person p;

	cout << "对象 p 所占的内存空间大小:" << sizeof(p) << " 字节" << endl;
}

int main()
{
	test();

	cout << endl;
	system("pause");
	return 0;
}

        从上述代码和结果图中可以看出,当在类中定义一个 静态成员变量 时,对象 p 占用 1 个内存空间,这和空类时对象 p 所占用的空间大小相等,这说明了静态成员函数不属于对象的成员,它是类的成员。   

4、代码清单 2

        对代码清单 1 下列的代码进行简单汇总。

#include<iostream>
#include<string>

using namespace std;

class Person
{
	//非静态成员变量,属于类的对象上
	int p_age;

	//静态成员函数,不属于类的对象上
	static int p_height;

	//非静态成员函数,不属于类的对象上
	void func1() {};

	//静态成员变量,不属于类的对象上
	static void func2() {};
};

void test()
{
	Person p;

	cout << "对象 p 所占的内存空间大小:" << sizeof(p) << " 字节" << endl;
}

int main()
{
	test();

	cout << endl;
	system("pause");
	return 0;
}

        从上述代码和结果图中可以看出,对象 p 之所以是 4 个字节,是因为非静态成员变量(int p_age;)是对象的成员,除此之外的其他成员变量和函数都是类的成员。

5、总结 

        本期的分享总结就到这里了,如果有疑问的小伙伴,我们在评论区交流嗷~~~,笔者必回,我们下期再见啦 !!

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

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

相关文章

SpringBoot 增强Controller方法,@ControllerAdvice注解的使用

参考资料 ControllerAdvice 用法SpringBoot使用ControllerAdvice注解 目录 一. ControllerAdvice注解作用二. ControllerAdvice注解 assignableTypes属性2.1 ControllerAdvice增强类2.2 Controller层2.3 效果 三. ControllerAdvice注解 basePackages属性3.1 ControllerAdvic…

踩坑|以为是Redis缓存没想到却是Spring事务!

前言 最近碰到了一个Bug&#xff0c;折腾了我好几天。并且这个Bug不是必现的&#xff0c;出现的概率比较低。一开始我以为是旧数据的问题&#xff0c;就让测试重新生成了一下数据&#xff0c;重新测试。由于后面几轮测试均未出现&#xff0c;我也就没太在意。 可惜好景不长&…

【LeetCode】260. 只出现一次的数字 III

260. 只出现一次的数字 III&#xff08;中等&#xff09; 思路 这道题是136. 只出现一次的数字 的进阶版&#xff0c;需要找出两个仅出现一次的元素。有了上一题的基础&#xff0c;我们很容易就想到要用异或来解决&#xff0c;但是由于这题最终会剩下两个不同的元素&#xff0…

设置和使用DragGAN:搭建非官方的演示版

DragGAN的官方版还没有发布&#xff0c;但是已经有非官方版的实现了&#xff0c;我们看看如何使用。DragGAN不仅让GAN重新回到竞争轨道上&#xff0c;而且为GAN图像处理开辟了新的可能性。正式版本将于本月发布。但是现在已经可以在一个非官方的演示中试用这个新工具了 DragGAN…

数据结构:二叉树(初阶)

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家解读一下二叉树方面的相关知识点&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通 …

Unix/C/C++进阶--SocketCAN 编程

Unix/C/C进阶--SocketCAN 编程 1 介绍1.1 socketcan 简介1.2 can 发展历程1.3 can总线优点 2 知识点2.1 CAN详解--书籍、网站2.2 CAN详解--CAN与com口介绍2.3 CAN详解--各家CAN分析仪与软件的比较2.4 转载&#xff1a;CAN总线终端电阻2.5 如何破解汽车--CAN协议&#xff08;can…

3.8 电路布线

博主简介&#xff1a;一个爱打游戏的计算机专业学生博主主页&#xff1a; 夏驰和徐策所属专栏&#xff1a;算法设计与分析 1.最优子结构的证明&#xff1a; 我的理解&#xff1a; 对于电路布线问题的最优子结构性质&#xff0c;我们可以通过数学推导进行证明。下面是对证明的…

conda在 powershell下不能激活虚拟环境

这里写自定义目录标题 问题原因解决办法增加环境变量修改PowerShell 策略初始化conda环境安装或更新conda 结果 问题原因 powershell正常是不行的&#xff0c;但是在cmd中是可以的 问题产生的原因有很多&#xff1a; 必须无法识别activate.bat激活无反应 解决办法 增加环…

【JavaSE】Java基础语法(四十六):枚举

文章目录 1. 概述2. 定义格式3. 枚举的特点4. 枚举的方法 1. 概述 枚举是一种特殊的数据类型&#xff0c;它列出了一组预定义的常量&#xff0c;并使用标识符来引用这些常量。枚举的用途很广泛&#xff0c;下面列举了几个常见的应用场景&#xff1a; 管理常量&#xff1a;如果您…

计算机组成原理---第三章存储系统 习题详解版

&#xff08;一&#xff09;精选课内习题 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 &#xff08;二&#xff09;精选课后习题 1.设有一个具有20位地址和32位字长的存储器&#xff0c;问&#xff1a; (1)该存储器能存储多少个字节的信息&#xff1f; (2)如果存储器由512k8位的SR…

Linux :: vim 编辑器:详解:文本复制/粘贴/剪切/删除 与 撤销普通操作及撤销撤销操作

前言&#xff1a;本篇是 Linux 基本操作篇章的内容&#xff01; 笔者使用的环境是基于腾讯云服务器&#xff1a;CentOS 7.6 64bit。 学习集&#xff1a; C 入门到入土&#xff01;&#xff01;&#xff01;学习合集Linux 从命令到网络再到内核&#xff01;学习合集 前文&#x…

chatgpt赋能python:Python去掉None:提高代码效率,优化SEO

Python去掉None&#xff1a;提高代码效率&#xff0c;优化SEO 作为一名有10年Python编程经验的工程师&#xff0c;我发现Python中会频繁出现None类型的变量。这种情况在代码中一旦过多&#xff0c;就会影响程序的效率&#xff0c;同样也会影响SEO的排名。因此&#xff0c;为提…

【数据仓库架构】什么是 Azure Synapse,它与 Azure Data Bricks 有何不同?

Azure Synapse Analytics 是一项针对大型公司的无限信息分析服务&#xff0c;它被呈现为 Azure SQL 数据仓库 (SQL DW) 的演变&#xff0c;将业务数据存储和宏或大数据分析结合在一起。 在处理、管理和提供数据以满足即时商业智能和数据预测需求时&#xff0c;Synapse 为所有工…

Hive学习---5、文件格式和压缩、企业级调优

1、文件格式和压缩 1.1 Hadoop压缩概述 由于Hive是相当于与Hadoop的客户端&#xff0c;所以hadoop会啥压缩&#xff0c;Hive基本就会啥压缩。 压缩格式算法文件扩展名是否可切分DEFLATEDEFLATE.deflate否GzipDEFLATE.gz否bzip2bzip2.bz2是LZOLZO.lzo是SnappySnappy.snappy否…

word恢复和粘贴按钮变灰色,不可用怎么办?

如果 Word 中的恢复和粘贴按钮变成灰色&#xff0c;可能是由于以下原因之一&#xff1a; 1. 文档处于只读模式。 2. 与 Office 相关的某些组件已损坏或缺失。 3. Word 的文件权限被配置为只读。 以下是一些可能的解决方法&#xff1a; 1. 检查文档是否处于只读模式。 如果是…

随机数发生器设计(三)

随机数发生器设计&#xff08;三&#xff09;- 熵估计和健康测试 熵估计健康测试 熵估计 考虑都熵源的多样性&#xff0c;建立一个通用的熵估计模型比较困难。本文采用nist.sp.800-90B推荐的Markov评估。详见 https://doi.org/10.6028/NIST.SP.800-90B。 执行Markov评估时&am…

chatgpt赋能python:用Python向手机发送信息是如何实现的?

用Python向手机发送信息是如何实现的&#xff1f; 在今天的信息时代&#xff0c;随时随地保持联系已经成为生活不可或缺的一部分。随着技术的发展&#xff0c;我们可以使用各种方式发送和接收信息&#xff0c;而使用Python向手机发送短信是其中一种非常方便的方式。 Python的…

I.MX6ull EPIT定时器

一 简介 EPIT定时器是一种增强的周期中断定时器&#xff0c;完成周期性中断定时的功能。 具有以下特点 EPIT定时器是一个32位的定时器 时钟源可选的向下计数器 EPIT 共有 3 个时钟源可选择&#xff0c;ipg_clk、ipg_clk_32k 和 ipg_clk_highfreq 当计数值和比较值相等的时候…

兼顾性能+实时性处理缓冲数据解决方案

我们经常会遇到这样的数据处理应用场景&#xff1a;我们利用一个组件实时收集外部交付给它的数据&#xff0c;并由它转发给一个外部处理程序进行处理。考虑到性能&#xff0c;它会将数据存储在本地缓冲区&#xff0c;等累积到指定的数量后打包发送&#xff1b;考虑到实时性&…

ChatGPT与软件架构(3) - 软件架构提示工程

高效利用ChatGPT辅助研发的关键是在研发生命周期的不同阶段采用对应提示获取有益的帮助。原文: Leveraging Prompt Engineering in Software Architecture with ChatGPT 软件架构开发生命周期转型。 Beth Smith Unsplash 简介 作为解决方案架构师&#xff0c;有必要掌握软件架构…