C嘎嘎~~[类 中篇]

news2024/9/20 10:42:20

类 中篇

  • 6.类的实例化
  • 7.类对象模型
  • 8.this指针
    • 8.1this指针是什么
    • 8.2this指针的特性

6.类的实例化

什么叫类的 实例化??

首先, 我们应该关注这个"实" — 实际存在的, 它的反义词是 “虚” — 不存在的. ==> 类中的成员变量是虚的(相当于声明), 在类外面创建的对象是实际存在的(相当于定义).

用类类型创建对象的过程, 成为类的实例化.

  1. 类是对对象进行描述的, 是一种模型一样的东西, 限定了类有哪些成员. 类是没有分配实际的内存空间,变相地说明了类中的成员变量是一种声明哦

    class PersonInfor
    {
    public:
    	void PrintPersonInfor()
    	{
    		cout << _name << endl;
    		cout << _adress << endl;
    		cout << age << endl;
    	}
    
    private:
    	char _name[20];
    	char _adress[30];
    	int _age;
    
    };
    
    int main()
    {
    	PersonInfor::_name; // error C2597: 对非静态成员“PersonInfor::_name”的非法引用
                            // message : 参见“PersonInfor::_name”的声明
    	PersonInfor::_adress; // error C2597: 对非静态成员“PersonInfor::_adress”的非法引用
                               // message : 参见“PersonInfor::_adress”的声明
    	PersonInfor::_age; // error C2597: 对非静态成员“PersonInfor::_age”的非法引用
                            // message : 参见“PersonInfor::_age”的声明
    
    }
    

    肯定有些老铁会尝试上面的做法, 很明显是错误的!!!

    1. 这些老铁应该是这样想的: PersonInfor 是一个类名, 那么就存在类域, 我就可以用域作用限定符 (😃 来访问类中的成员变量~~

    2. 错误原因: 其实这种说法就是错误的~ ,我们想一想什么叫做访问? 访问的东西肯定要有内存空间吧, 要不访问个啥呢~~

      其实,很多词语就暗着内存空间: 访问, 初始化, 有可能你现在看这些一点反应都没有, 学到后面这些用途大着嘞.

  2. 一个类可以实例化多个对象, 这点应该不用多说(类是一种变量类型, 相当于我们常见的 int, double, char…). 但是实例化出的对象 占用的物理空间只存储了成员变量, 即成员函数是不在对象中的.

    class PersonInfor
    {
    public:
    	void PrintPersonInfor()
    	{
    		cout << _name << endl;
    		cout << _adress << endl;
    		cout << age << endl;
    	}
    
    private:
    	char _name[20];
    	char _adress[30];
    	int _age;
    
    };
    
    int main()
    {
    	PersonInfor p;
    	printf("类的大小 = %d\n", sizeof(PersonInfor)); // 56
    	printf("对象的大小 = %d\n", sizeof(p)); // 56
    }
    
    
    • 得到的知识点:
      1. 根据结构体的所学知识, 我们不难知道成员变量的大小就是 56, 而对象 和 类的大小也是56, 验证了成员函数不是包含在对象中的.
      2. sizeof(对象) = sizeof(类)
      3. 以 arr.Push( ) 为例子: 调用这个函数, 是不会在对象里面去寻找的, 因为成员函数没在对象里.
    • 疑惑点:
      1. 成员函数到底在哪里??
      2. 上面的代码, 我这样调用可以吗? PersonInfor :: PrintPersonInfor()??

先对类的实例化打一个形象地比喻:

声明就好比是一张房屋的设计图纸, 成员变量就是那图纸上的一个个房间, 成员函数先靠边~~

设计图纸终归也就是一张纸而已, 里面的设计的东西再怎么好也是不存在的.

而我们的对象就是把这个图纸实际化 ==> 真真切切地造一个房子出来. 房子是按照图纸建造的, 里面的东西肯定只有也只能有这些房间(成员变量) ==> 类是对对象进行描述的, 是一种模型一样的东西, 限定了类有哪些成员.

这时候, 我们想到那娱乐设施呢, 就比如篮球场~, 篮球场是一家建一个 还是 一个小区建一个好一些?? 答案不言而喻, 一个小区建一个, 不仅经济实惠, 还能融洽小区关系呢~~ 成员函数就好比是这篮球场, 它是不会存放在一个个对象中的(占空间), 而是存放在一个公共位置, 大家都可以使用哦.


回答:

  1. 成员函数的存放位置在一个公共位置, 同一个类型的对象都可以调用

  2. PersonInfor :: PrintPersonInfor() 是不可以的:

    1. 老铁是这样想的: 反正成员函数是不在对象中的, 那我就可以不用对象去访问它了吧

    2. 错误原因: 其实这里有个 this指针,这个后面会讲~


      或者大家有么有想过下面的几个问题:

      1. 每个对象调用的成员函数都是一样的吗?
      2. 如果是一样的, 那么为什么多个对象调用有多个不同的结果??

7.类对象模型

一个类的大小,实际就是该类中”成员变量”之和,当然要注意内存对齐

注意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类的对象

  • 内存对齐的规则:
  1. 第一个成员在与结构体偏移量为0的地址处
  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。 VS中默认的对齐数为8
  3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍
  4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是 所有最大对齐数(含嵌套结构体的对齐数)的整数倍
  • 小问题:
  1. 结构体怎么对齐? 为什么要进行内存对齐?
  2. 如何让结构体按照指定的对齐参数进行对齐?能否按照3、4、5即任意字节对齐?
  3. 什么是大小端?如何测试某台机器是大端还是小端,有没有遇到过要考虑大小端的场景?

8.this指针

通过前面的学习, 相信大家对this指针充满了好奇心
this指针对我们以后的学习有着无与伦比的作用

8.1this指针是什么

class Data
{
public:
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	void Print()
	{
		cout << _year << " " << _month << " " << _day << endl;
	}

private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	// 对象实例化
	Data d1;
	Data d2;

	// 调用函数
	d1.Init(2023, 12, 1);
	d2.Init(2023, 12, 12);
	d1.Print();
	d2.Print();

}

this指针, C++编译器给每个"非静态的成员函数" 增加了一个隐藏的指针参数, 让该指针指向当前对象(函数运行时调用该函数的对象), 在函数体中所有"成员变量"的操作, 都是通过该指针去访问. 只不过所有的操作对用户是透明的, 即不需要用户来传递, 编译器自己完成.

上面, 我们留了一个问题: “如果每个对象调用的成员函数是一样的, 那么为什么多个对象调用有多个不同的结果??”, 这个时候就能过给大家解答了:

让该指针指向当前对象(函数运行时调用该函数的对象), 在函数体中所有"成员变量"的操作, 都是通过该指针去访问 ==>

d1.Init() ==> d1.Init(&d1), d1.Print( ) ==> d1.Print(&d1)

这样大家就明白了: 为什么调用的同一个函数, 为什么结果不一样~~


补充:

不同对象调用的成员函数是相同的原因:


8.2this指针的特性

  1. this指针的原型是:对象类型* const this, 即在成员函数中, 不能给this指针赋值, 不能改变this指针.

  2. this指针不能在形参 和 实参显示传参, 但是能够在成员函数中使用(这个以后还有大用途)

    1. this指针本质是成员函数的形参, 当对象调用成员函数时, 将对象的地址作为实参传递给this形参, 所以对象是不存储this指针的.
    2. 切记: this指针是成员函数的"第一个隐含的指针形参", 用户不需要也不能传递

    • 解决上面的两个疑问:

      1. “PersonInfor :: PrintPersonInfor() 是不可以的”

        这个是因为成员函数不知道该传递啥~, :: 是访问的意思哎, 并没有传递对象的地址哎

      2. 那有些老铁就会说: PersonInfor :: PrintPersonInfor(对象的地址) , 这样行吧??

        你的这些小聪明, 我都是看在眼里的哈哈~~

        这里虽然传递了对象的地址, 但是你忽略了一点:this指针在形参和实参是不显示的哎~~

    • 小问题:

      1. this指针存放在哪里?

        因为this指针是成员函数的形参, 所以this指针是跟普通函数一样存放在函数调用的栈区的, 函数调用结束就销毁了

      2. this指针可以为空吗?

        分情况:

        1. 如果this指针传过去没有访问this所指向的内容, 这样是可以的
        2. 如果this指针传过去有访问this所指向的内容, 这样会报运行错误

        通过下面的俩个例子来解释一下:

        class test
        {
        public:
        	void test1()
        	{
        		cout << "test1(_)" << endl; // 并没有访问this指针
        	}
        
        	void test2()
        	{
        		cout << _a << endl; // 访问了this指针
        	}
        
        private:
        	int _a;
        };
        
        int main()
        {
        	test* a = nullptr;
        	a->test1(); // test1(_)
        	a->test2(); // error
        
        	return 0;
        }
        

        在这里插入图片描述

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

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

相关文章

《程序员面试金典(第6版)》面试题 16.06. 最小差(双指针,pair数据结构)

题目描述 给定两个整数数组a和b&#xff0c;计算具有最小差绝对值的一对数值&#xff08;每个数组中取一个值&#xff09;&#xff0c;并返回该对数值的差 示例&#xff1a; 输入&#xff1a;{1, 3, 15, 11, 2}, {23, 127, 235, 19, 8}输出&#xff1a;3&#xff0c;即数值对(…

Power BI动态日期轴方法总结

趋势&#xff0c;应该是我们做可视化时最熟悉的一个词了&#xff0c;看趋势自然离不开日期&#xff0c;年度趋势&#xff0c;月趋势&#xff0c;周趋势等等。Power BI中我们可以借助于计算表&#xff0c;计算组&#xff0c;字段参数来实现动态实时轴的效果。 计算表实现动态日…

Node.js--基础

一、Node.js是什么 Node.js is a JavaScript runtime built on Chrome’s V8 JavaScript engine. 1、特性 Node.js 可以解析JS代码&#xff08;没有浏览器安全级别的限制&#xff09;提供很多系统级别的API&#xff0c;如&#xff1a; 文件的读写 (File System)进程的管理 …

每日一个小技巧:1分钟告诉你文字转图片的方法有哪些

在数字时代&#xff0c;信息传递快速便捷&#xff0c;但文字在传递中却显得单调乏味&#xff0c;难以吸引人们的眼球。为了解决这个问题&#xff0c;越来越多的人开始寻找方法将文字转化为图片。文字转图片不仅能够让文字更具视觉冲击力&#xff0c;还能够在社交媒体、广告宣传…

Nginx常见应用场景

文章目录 场景一&#xff1a;代理静态文件场景二&#xff1a;代理服务器 本教程讲述 Nginx 的常见应用场景。内容接上文&#xff1a;Nginx基本配置。 前提&#xff1a;假设我们已经安装好了 Nginx&#xff0c;并启动成功。 场景一&#xff1a;代理静态文件 Nginx 一个常用的功…

Hilt 和协程助力启动框架搭建:解决代码混乱和初始化策略问题

关于Hilt的使用&#xff0c;目前已经比较普及了&#xff0c;想必大家已经知道。今天说的是一个如何利用Hilt来做一个启动框架的故事。 是否经历过大型项目的启动优化&#xff0c;一遍过去无任何效果&#xff0c;第二遍过去好几处报错&#xff0c;第三遍过去启动不了&#xff0…

开放耳机有什么优缺点,列举出几款口碑不错的开放式耳机

开放式耳机是通过骨头振动传递声音&#xff0c;而不是通过耳道或鼓膜&#xff0c;因此它具有许多优势&#xff0c;比如可以在运动过程中保持对环境的感知&#xff0c;并避免对听力造成伤害。随着科技的进步和用户需求的增加&#xff0c;开放式耳机也在不断更新。目前市面上的开…

springboot+nodejs+vue众筹项目管理系统平台系统

筹资人&#xff08;企业&#xff09;&#xff1a; 1&#xff0c;可以后台注册并登录&#xff0c;发布项目情况&#xff0c;众筹项目需要管理员审核通过后才能展现在前台&#xff0c;没有审核或者审核不通过不会在前台展示&#xff1b; 众筹项目包括项目名称&#xff0c;项目分类…

盲目自学网络安全只会成为脚本小子?

前言&#xff1a;我们来看看怎么学才不会成为脚本小子 一&#xff0c;怎么入门&#xff1f; 1、Web 安全相关概念&#xff08;2 周&#xff09; 了解网络安全相关法律法规 熟悉基本概念&#xff08;SQL 注入、上传、XSS、CSRF、一句话木马等&#xff09;。 通过关键字&…

springboot整合flowable的简单使用

内容来自网络整理&#xff0c;文章最下有引用地址&#xff0c;可跳转至相关资源页面。若有侵权请联系删除 环境&#xff1a; mysql5.7.2 springboot 2.3.9.RELEASE flowable 6.7.2 采坑&#xff1a; 1.当前flowable sql需要与引用的pom依赖一致&#xff0c;否则会报library…

管理后台项目-07-菜单管理和动态展示菜单和按钮

目录 1-菜单管理 1.1-菜单管理列表 1.2-添加|修改功能 1.3-删除菜单 2-动态菜单按钮展示 2.1-路由文件的整理 2.2-动态展示不同的路由 1-菜单管理 当用户点击菜单管理的时候&#xff0c;会展示当前所有菜单&#xff0c;树型结构展示...并且可以对菜单进行新增编辑删除操…

倾斜摄影超大场景的三维模型在网络发布应用遇到常见的问题浅析

倾斜摄影超大场景的三维模型在网络发布应用遇到常见的问题浅析 倾斜摄影超大场景的三维模型在网络发布应用时&#xff0c;常见的问题包括&#xff1a; 1、加载速度慢。由于数据量巨大&#xff0c;网络发布时需要将数据文件分割成多个小文件进行加载&#xff0c;这可能会导致页…

Sonatype Nexus兼容apk格式仓库

Sonatype Nexus兼容apk格式仓库 sonatype/nexus3 当前最新版本&#xff1a;sonatype/nexus3:3.52.0 查看nexus支持的仓库格式 创建一个nexus 容器&#xff1a; docker run -d -p 8081:8081 --name nexus sonatype/nexus3:3.52.0查看启动日志&#xff1a; docker logs nexu…

HTML5画布(图像)

案例1&#xff1a; <!DOCTYPE html> <html> <head lang"en"><meta charset"UTF-8"><title></title><script>window.onloadfunction(){var cdocument.getElementById("myCanvas");var cxt c.getConte…

Vue3 手把手按需引入 Echarts

背景&#xff1a;新项目采用 Vue3 作为前端项目框架&#xff0c;避免不了要使用 echarts&#xff0c;但是在使用的时候&#xff0c;出现了与 Vue2 使用不一样的地方&#xff0c;所以特别记下来&#xff0c;希望给到有需要的同学一些帮助。 下载Echarts依赖 # 自己使用的yarn y…

《Odoo开发者模式必知必会》—— 缘起

Odoo作为业界优秀的开源商务软件&#xff0c;在全球范围内拥有广泛的使用者。在领英国际&#xff0c;可以搜索到全球很多国家都有大量odoo人才需求的招聘信息。在国内&#xff0c;虽然已经有为数不少的企业&#xff0c;他们或者已经使用odoo&#xff0c;或者正在了解odoo&#…

支付宝异步通知说明

如何设置异步通知地址 不同接口接收异步通知设置方式不同&#xff0c;可查看 哪些接口支持触发异步。 设置 notify_url 接收异步 对于支付产生的交易&#xff0c;支付宝会根据原始支付 API 中传入的异步通知地址 notify_url&#xff0c;通过 POST 请求的形式将支付结果作为参…

从零开始学习CTF的完整指南

前言 想要学习CTF却不知从何开始&#xff1f;本文提供了一份完整的指南&#xff0c;从Linux系统基础、网络协议基础、二进制分析、Web安全、杂项题型以及算法与密码学等方面&#xff0c;为零基础小白提供了学习路线和知识点概述。 网络安全 网络安全是 CTF 的基础&#xff0…

还不知道怎么 Mock ,用这 6款工具

以下是几个常用的国外可以mock测试的工具&#xff0c;供参考&#xff1a; MockServer: MockServer 是一个开源的 API mock 测试工具&#xff0c;提供了强大的模拟服务器和 mock 服务功能。MockServer 支持多种语言和格式&#xff0c;包括 Java、.NET、REST、SOAP 等。 WireMoc…

优思学院|做质量管理有七大工具,都是什么?

质量管理七大工具&#xff08;Seven Basic Quality Tools&#xff09;是由日本质量大师石川馨于20世纪50年代首次提出&#xff0c;这些工具被广泛应用于制造业和服务业的质量管理实践中&#xff0c;优思学院认为这七个工具除了是质量人常用的工具之外&#xff0c;也可作为学习六…