类与对象C++详解(上)

目录

1.类的定义

1.1 类定义格式

补充: struct与class的区别(c语言与c++)

1.2 访问限定符

1.3 类域

2.实例化

3.对象大小

4.this指针


1.类的定义

1.1 类定义格式

        class为定义类的关键字,Stack为类的名字,{}中为类的主体,注意类定义结束时后⾯分号不能省 略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量;类中的函数称为类的⽅法或 者成员函数。

        为了区分成员变量,⼀般习惯上成员变量会加⼀个特殊标识,如成员变量前⾯或者后⾯加_或者m 开头,注意C++中这个并不是强制的,只是⼀些惯例,具体看公司的要求。

         C++中struct也可以定义类,C++兼容C中struct的⽤法,同时struct升级成了类,明显的变化是 struct中可以定义函数,⼀般情况下我们还是推荐⽤class定义类。

        定义在类⾯的成员函数默认为inline。

        他的定义很简单,我们来解释一下inline,inline我们这里先简单介绍一下:inline函数指的是内联函数,在代码运行过程中不会出现栈帧,而是直接在原位展开,给一段简单的代码:

        像这个print函数,在main函数中实际调用的时候,就会直接展开,我们看一下他的汇编代码

此时他没有调用函数的call指令(有的话代表着创建了函数栈帧,而不是原地展开)。

下一个需要强调的地方,c++中的struct基本就是class,他的用法和在c语言中的还不一样,我这里简单写个例子:

补充: struct与class的区别(c语言与c++)

C++:

        但我们相同的代码放到c语言中时

        报错,那我们应该怎么改呢?

法一:

此时原理是将struct Date重命名成了Date,所以能直接使用。

法2:

C++这里对c语言中的struct进行了改变,所以不要以为他们是一样的东西,其中还有一个区别是c语言不允许结构体中出现函数,

而c++却支持:

        好,讲的讲的就跑偏了,我们切回正题。

1.2 访问限定符

1.C++⼀种实现封装的⽅式,⽤类将对象的属性与⽅法结合在⼀块,让对象更加完善,通过访问权限 选择性的将其接⼝提供给外部的⽤⼾使⽤。

2.public修饰的成员在类外可以直接被访问;protected和private修饰的成员在类外不能直接被访 问,protected和private是⼀样的,以后继承章节才能体现出他们的区别。

3.访问权限作⽤域从该访问限定符出现的位置开始直到下⼀个访问限定符出现时为⽌,如果后⾯没有 访问限定符,作⽤域就到}即类结束。

4.class定义成员没有被访问限定符修饰时默认为private,struct默认为public。

5.⼀般成员变量都会被限制为private/protected,需要给别⼈使⽤的成员函数会放为public。

这个很好理解吧,简单举个例子:

1.3 类域

1.类定义了⼀个新的作⽤域,类的所有成员都在类的作⽤域中,在类体外定义成员时,需要使⽤::作 ⽤域操作符指明成员属于哪个类域。

 2.类域影响的是编译的查找规则,下⾯程序中Init如果不指定类域Stack,那么编译器就把Init当成全 局函数,那么编译时,找不到array等成员的声明/定义在哪⾥,就会报错。指定类域Stack,就是知 道Init是成员函数,当前域找不到的array等成员,就会到类域中去查找。

2.实例化

        什么是实例化,简单来说:

d1,d2就是两个实例化出来的两个具体对象

注意注释:声明!

3.对象大小

这里会遵循一个叫做内存对齐的原则,在计算过程中,这个我之前讲过,look this:结构体内存对齐(你可能不知道但很重要的知识)-CSDN博客

大家可以看一眼,这部分和c语言是一样的,but   ,c++中的类和c语言中的结构体的一个显著区别,类中支持函数,那函数占多大呢?我们来实践一下

接着我们把函数注释掉:

答案显而易见,就是不会去额外占用空间,为什么呢?

函数不会存在对象内部

⾸先函数被编译后是⼀段指令,对象中没办法存储,这些指令 存储在⼀个单独的区域(代码段),那么对象中⾮要存储的话,只能是成员函数的指针。再分析⼀下,对 象中是否有存储指针的必要呢,Date实例化d1和d2两个对象,d1和d2都有各⾃独⽴的成员变量 _year/_month/_day存储各⾃的数据,但是d1和d2的成员函数Init/Print指针却是⼀样的,存储在对象 中就浪费了。如果⽤Date实例化100个对象,那么成员函数指针就重复存储100次,太浪费了。这⾥需 要再额外哆嗦⼀下,其实函数指针是不需要存储的,函数指针是⼀个地址,调⽤函数被编译成汇编指 令[call 地址]

4.this指针

        每一个实例化之后的对象,都有一个this指针指向他,可以访问内部的成员变量

Date类中有Init与Print两个成员函数,函数体中没有关于不同对象的区分,那当d1调⽤Init和 Print函数时,该函数是如何知道应该访问的是d1对象还是d2对象呢?那么这⾥就要看到C++给了 ⼀个隐含的this指针解决这⾥的问题

 编译器编译后,类的成员函数默认都会在形参第⼀个位置,增加⼀个当前类类型的指针,叫做this 指针。⽐如Date类的Init的真实原型为, void Init(Date* const this, int year, int month, int day)

类的成员函数中访问成员变量,本质都是通过this指针访问的,如Init函数中给_year赋值, this->_year = year;

 C++规定不能在实参和形参的位置显⽰的写this指针(编译时编译器会处理),但是可以在函数体内显 ⽰使⽤this指针。

        这就是类和对象的一个基础知识,我打算分三篇来讲类和对象,这是第一篇,接下来有两个题目给大家做一下

下⾯程序编译运⾏结果是() A、编译报错 B、运⾏崩溃 C、正常运⾏


#include<iostream>
using namespace std;
class A
{
public:void Print(){cout << "A::Print()" << endl;}
private:int _a;
};
int main()
{A* p = nullptr;p->Print();return 0;
}

答案应该是正确运行,大家可以去复制上运行一下,为什么呢?

为什么呢?明明p是个空指针但还是能够运行?原因在于,没有对p进行解引用,而且,我们在之前说过,成员函数不在对象内部存储,且在成员函数内部,也没有调用成员变量,所以最后能够正确运行。


#include<iostream>
using namespace std;
class A
{
public:void Print(){cout << _a;cout << "A::Print()" << endl;}
private:int _a;
};
int main()
{A* p = nullptr;p->Print();return 0;
}

那这段代码的运行结果呢?答案是崩溃了,首先不能是编译错误,因为编译解决的是语法问题,这个题语法没有错误,然后为什么是崩溃,因为他在函数内部进行了对成员访问,而this指针是个空指针

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

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

相关文章

LabVIEW 天然气水合物电声联合探测

天然气水合物被认为是潜在的清洁能源&#xff0c;其储量丰富&#xff0c;预计将在未来能源格局中扮演重要角色。由于其独特的物理化学特性&#xff0c;天然气水合物的探测面临诸多挑战&#xff0c;涉及温度、压力、电学信号、声学信号等多个参数。传统的人工操作方式不仅效率低…

Windows上安装Go并配置环境变量(图文步骤)

前言 1. 本文主要讲解的是在windows上安装Go语言的环境和配置环境变量&#xff1b; Go语言版本&#xff1a;1.23.2 Windows版本&#xff1a;win11&#xff08;win10通用&#xff09; 下载Go环境 下载go环境&#xff1a;Go下载官网链接(https://golang.google.cn/dl/) 等待…

神经网络常见激活函数 9-CELU函数

文章目录 CELU函数导函数函数和导函数图像优缺点pytorch中的CELU函数tensorflow 中的CELU函数 CELU 连续可微指数线性单元&#xff1a;CELU&#xff08;Continuously Differentiable Exponential Linear Unit&#xff09;,是一种连续可导的激活函数&#xff0c;结合了 ELU 和 …

《安富莱嵌入式周报》第350期:Google开源Pebble智能手表,开源模块化机器人平台,开源万用表,支持10GHz HRTIM的单片机,开源CNC控制器

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版&#xff1a; https://www.bilibili.com/video/BV1YPKEeyEeM/ 《安富莱嵌入式周报》第350期&#xff1a;Google开…

小米平板怎么和电脑共享屏幕

最近尝试使用小米平板和电脑屏幕分屏互联 发现是需要做特殊处理的&#xff0c;需要下载一款电脑安装包&#xff1a;小米妙享 关于这个安装包&#xff0c;想吐槽的是&#xff1a; 没有找到官网渠道&#xff0c;是通过其他网络方式查到下载的 不附录链接&#xff0c;原因是因为地…

(学习总结23)Linux 目录、通配符、重定向、管道、shell、权限与粘滞位

Linux 目录、通配符、重定向、管道、shell、权限与粘滞位 Linux 目录通配符重定向管道shell 介绍Linux 权限Linux 权限的概念用户切换命令 su Linux权限管理文件访问者的分类&#xff1a;常用文件类型与其标识符&#xff1a;文件基本权限和权限值的表示方法&#xff1a;更改文件…

深入解析操作系统控制台:阿里云Alibaba Cloud Linux(Alinux)的运维利器

作为一位个人开发者兼产品经理&#xff0c;我的工作日常紧密围绕着云资源的运维和管理。在这个过程中&#xff0c;操作系统扮演了至关重要的角色&#xff0c;而操作系统控制台则成为了我们进行系统管理的得力助手。本文将详细介绍阿里云的Alibaba Cloud Linux操作系统控制台的功…

Android10 音频参数导出合并

A10 设备录音时底噪过大&#xff0c;让音频同事校准了下&#xff0c;然后把校准好的参数需要导出来&#xff0c;集成到项目中&#xff0c;然后出包&#xff0c;导出方式在此记录 设备安装debug系统版本调试好后&#xff0c; adb root adb remount adb shell 进入设备目录 导…

dnslog+sqlmap外带数据

目录 爆库 爆表 爆列 爆数据 sqlmapDNSlog 外带参数 –dns-domain参数注入 –dns-domain参数为dnslog平台的域名&#xff08;我们也可以使用本地&#xff09; 爆库 python sqlmap.py -u "http://127.0.0.1/sqli/less-8/index.php/?id1" -techniqueB -dns-dom…

sql注入中information_schema被过滤的问题

目录 一、information_schema库的作用 二、获得表名 2.1 sys.schema_auto_increment_columns 2.2 schema_table_statistics 三、获得列名 join … using … order by盲注 子查询 在进行sql注入时&#xff0c;我们经常会使用information_schema来进行爆数据库名、表名、…

Flutter 常见布局模型

Flutter的常见的布局模型有容器&#xff08;Container&#xff09;、弹性盒子布局&#xff08;Flex、Row、Column、Expanded&#xff09;、流式布局&#xff08;Wrap、Flow&#xff09;、层叠布局&#xff08;Stack、Position&#xff09;、滚动布局&#xff08;ListView、Grid…

深度学习框架探秘|TensorFlow:AI 世界的万能钥匙

在人工智能&#xff08;AI&#xff09;蓬勃发展的时代&#xff0c;各种强大的工具和框架如雨后春笋般涌现&#xff0c;而 TensorFlow 无疑是其中最耀眼的明星之一。它不仅被广泛应用于学术界的前沿研究&#xff0c;更是工业界实现 AI 落地的关键技术。今天&#xff0c;就让我们…

TypeScript 与后端开发Node.js

文章目录 一、搭建 TypeScript Node.js 项目 &#xff08;一&#xff09;初始化项目并安装相关依赖 1、创建项目目录并初始化2、安装必要的依赖包 &#xff08;二&#xff09;配置 TypeScript 编译选项&#xff08;如模块解析方式适合后端&#xff09; 二、编写服务器代码 &a…

DDD该怎么去落地实现(3)通用的仓库和工厂

通用的仓库和工厂 我有一个梦&#xff0c;就是希望DDD能够成为今后软件研发的主流&#xff0c;越来越多研发团队都转型DDD&#xff0c;采用DDD的设计思想和方法&#xff0c;设计开发软件系统。这个梦想在不久的将来是有可能达成的&#xff0c;因为DDD是软件复杂性的解决之道&a…

国家队出手!DeepSeek上线国家超算互联网平台!

目前,国家超算互联网平台已推出 DeepSeek – R1 模型的 1.5B、7B、8B、14B 版本,后续还会在近期更新 32B、70B 等版本。 DeepSeek太火爆了!在这个春节档,直接成了全民热议的话题。 DeepSeek也毫无悬念地干到了全球增速最快的AI应用。这几天,国内的云计算厂家都在支持Dee…

内容中台驱动企业数字化内容管理高效协同架构

内容概要 在数字化转型加速的背景下&#xff0c;企业对内容管理的需求从单一存储向全链路协同演进。内容中台作为核心支撑架构&#xff0c;通过统一的内容资源池与智能化管理工具&#xff0c;重塑了内容生产、存储、分发及迭代的流程。其核心价值在于打破部门壁垒&#xff0c;…

算法1-1 玩具谜题

题目描述 小南有一套可爱的玩具小人&#xff0c;它们各有不同的职业。 有一天&#xff0c;这些玩具小人把小南的眼镜藏了起来。小南发现玩具小人们围成了一个圈&#xff0c;它们有的面朝圈内&#xff0c;有的面朝圈外。如下图&#xff1a; 这时 singer 告诉小南一个谜题&…

vs2022支持.netframework4.0

下载nuget包 .netframework4.0 解压nuget 复制到C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework 参考 https://www.cnblogs.com/bdqczhl/p/18670152 https://blog.csdn.net/xiaomeng1998_/article/details/135979884

数据治理常用的开源项目有哪些?

数据治理是企业在大数据时代中确保数据质量、安全性和可用性的关键环节。开源项目在数据治理中扮演着重要角色&#xff0c;提供了灵活、经济高效且功能强大的解决方案。以下是一些常用的开源数据治理项目&#xff1a; Apache Atlas&#xff1a; 功能&#xff1a;元数据管理、数…

登录弹窗效果

1&#xff0c;要求 点击登录按钮&#xff0c;弹出登录窗口 提示1&#xff1a;登录窗口 display:none 隐藏状态&#xff1b; 提示2&#xff1a;登录按钮点击后&#xff0c;触发事件&#xff0c;修改 display:block 显示状态 提示3&#xff1a;登录窗口中点击关闭按钮&#xff0…