当前位置: 首页 > news >正文

C++-类与对象基础

一,类的定义

1.1类定义格式

class为定义类的关键字,Stack为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。类体中内容称为mian类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数。比如我们下面的一个简单的栈结构例子(不完整,作为引子使用):

using namespace std;class Stack
{
public:void Init(int n = 4){int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == nullptr){perror("realloc fail!");exit(EXIT_FAILURE);}_arr = tmp;top = 0;capacity = n;}void Destory(){free(_arr);_arr = nullptr;top = capacity = 0;}
private:int* _arr;int top;int capacity;
};int main()
{Stack d1;d1.Destory();return 0;
}

我们可以看到,类的使用方法与我们C中所学习的结构体非常类似,且class定义的类名可以直接代表类型,不需要我们再去使用typedef,而我们的C++中strcut也升级为了类,在struct中可以定义函数,但我们一般还是在C++中使用class定义类。

除此之外,我们的类的成员函数前都默认加有我们的inline:

void Init(int n = 4)//inline void Init(int n = 4)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == nullptr){perror("realloc fail!");exit(EXIT_FAILURE);}_arr = tmp;top = 0;capacity = n;
}

1.2访问限定符

我们注意到,在上面的栈代码中有public与private,这就是我们的类的访问限定符,我们的类访问限定符一共有三种:

1.public修饰的成员在类外可以直接被访问;protected和private修饰的成员在类外不能直接被访问,protected和private是⼀样的,以后介绍到继承部分时才能体现出他们的区别。

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

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

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

1.3类域 

这部分其实与我们的namespace有些许类似,类域影响的是编译的查找规则,就比如说我们要直接使用上面代码中的Init函数,如果不指定类域Stack,那么编译器就把Init当成全局函数,那么编译时,找不到arr等成员的声明/定义在哪里,就会报错。指定类域Stack,就是知道Init是成员函数,当前域找不到的arr等成员,就会到类域中去查找。

class Stack
{
public:void Init(int n = 4){int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == nullptr){perror("realloc fail!");exit(EXIT_FAILURE);}_arr = tmp;top = 0;capacity = n;}
private:int* _arr;int top;int capacity;
};int main()
{Stack::Init();//正确调用方法Init();//编译器找不到Init函数return 0;
}

二,实例化

 2.1实例化的概念

1.用类类型在物理内存中创建对象的过程,称为类实例化出对象。

2.类是对象进行⼀种抽象描述,是⼀个模型⼀样的东西,限定了类有哪些成员变量,这些成员变量只是声明,没有分配空间,用类实例化出对象时,才会分配空间。

3.⼀个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类成员变量。所以简单来说,我们的类就像盖房子的图纸一样,对着图纸建造出我们的房子就是我们的实例化。

2.2对象大小

我们在上面说过,类的定义中是有函数的,成员变量的大小我们在C语言中就已经详细了解过了,不多赘述。我们来看类的成员函数,假如我们的成员函数也是占有空间的,那我们去定义100个类,是不是就要去至少实例化100个成员函数,但我们知道,在实际使用的时候,拿我们上面的Stack来举例:

class Stack
{
public:void Init(int n = 4){int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == nullptr){perror("realloc fail!");exit(EXIT_FAILURE);}_arr = tmp;top = 0;capacity = n;}void Destory(){free(_arr);_arr = nullptr;top = capacity = 0;}
private:int* _arr;int top;int capacity;
};int main()
{Stack d1;Stack d2;d1.Destory();d2.Destory();return 0;
}

可以看到,两个相同的类用的是同一个函数,这样不就造成了不必要的实例化了。其实,函数被编译后是⼀段指令,对象中没办法存储,这些指令存储在⼀个单独的区域(代码段),那么对象中非要存储的话,只能是成员函数的指针。同时函数指针是不需要存储的,函数指针是⼀个地址,调用函数被编译成汇编指令[call 地址], 其实编译器在编译链接时,就要找到函数的地址,不是在运行时找,只有动态多态是在运行时找,就需要存储函数地址,这个我们以后的文章会介绍。

 接下来我们来看几个例子:

class A
{public :void Print(){cout << _ch << endl;}
private:char _ch;int _i;
};
class B
{public :void Print(){//...}
};
class C
{};

对于A,我们可以轻松的算出其大小为8byte,但是C和B呢。猛一看,我们上面不是说过,只有实例化的对象才会分配空间,所以按照常理来说B和C均为0,但是实际上为1,为什么?

B b1;
C c1;

如果为0,那我们上面定义的两个b1和c1所分配的空间就是0,如果⼀个字节都不给,怎么表示对象存在过呢,所以这里给1字节,纯粹是为了占位标识对象存在。

三,this指针

当我们定义了两个Stack对象时,编译器是如何区分d1与d2呢。事实上,编译器会在编译的时候自动在后面补上一个this指针:
 

d1.Init(&d1);
d2.Init(&d2);void Init(int n = 4)//实际调用后void Init(Stack const* this,int n = 4)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == nullptr){perror("realloc fail!");exit(EXIT_FAILURE);}_arr = tmp;top = 0;capacity = n;
}

所以类的成员函数中访问成员变量,本质都是通过this指针访问的。除此之外,C++规定不能在实参和形参的位置显示的写this指针(编译时编译器会处理),但是可以在函数体内显示使用this指针。

下面让我们来看两个经典案例:

乍一看两个都对空指针进行了解引用,二者均会产生运行崩溃(切记编译错误为语法上的错误),但实际上只有第二种情况会报错。我们上面也说过,成员函数的调用与我们定义的对象没有关系,他们的使用实际是直接call使用的:

所以在第一种情况下并没有发生对空指针的解引用,但第二种则是需要成员变量去完成函数运转,所以会发生对空指针的解引用,进而导致编译报错。

四,C++中struct与class的区别

相关文章:

C++-类与对象基础

一&#xff0c;类的定义 1.1类定义格式 class为定义类的关键字&#xff0c;Stack为类的名字&#xff0c;{}中为类的主体&#xff0c;注意类定义结束时后面分号不能省略。类体中内容称为mian类的成员&#xff1a;类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者…...

嵌入式day20

feof&#xff1a; 检测文件是否到达结尾 ferroe&#xff1a; 检测文件是否发生错误 标准IO之文件定位 fseek&#xff08;&#xff09; SEEK_END 指向最后一个字节的后一个&#xff0c;继续加&#xff0c;写文件&#xff0c;会将文件扩大 ftell&#xff08;&#xff09; 获取…...

UE4 SLUA IOS打包报错解决办法

IOS打包报错&#xff1a;Fatal error "lua.h" file not found &#xff1a; SLua Unreal 在IOS远程打包编译的时候 Exteral没有copy过去&#xff0c;导致lua.h文件报错找不到&#xff0c;看了网上也没有写解决办法 错误信息截图&#xff1a; github上也有很多遇到改…...

SpringDI(依赖注入) 以及SpringIOC容器对Bean管理

一、SpringDI&#xff08;依赖注入&#xff09; 1.DI依赖注入 1.1 Spring DI的理解 关键字:名词解释 DI( Dependecy Inject&#xff0c;中文释义:依赖注入&#xff09;是对Ioc概念的不同角度的描述&#xff0c;是指应用程序在运行时&#xff0c;每一个bean对象都依赖IoC 容器…...

伯克利Linux系统管理: 脚本编写学习 课堂与实验(系统简洁保姆级学习)

Linux系列文章目录 补充内容 Windows通过SSH连接Linux 第一章 Linux基本命令的学习与Linux历史 第二章(上) Vim课堂与实验 文章目录 Linux系列文章目录一、前言二、学习内容&#xff1a;2.1 上课内容2.1.1 为什么要学习脚本编写&#xff1f;2.1.2 Bash编程语言2.1.3 SheBang2.…...

探索腾讯云AI代码助手的效能与实用性

前言开发环境配置项目实例应用一&#xff1a;功能介绍二&#xff1a;项目测试FFmpeg二次开发SDL应用加密播放器 帮助提升建议结语 ​ 前言 腾讯云的AI代码助手是一款强大的编码辅助工具&#xff0c;利用混元代码大模型技术&#xff0c;提供技术对话、代码补全、代码诊断和优化…...

清华大学终于把Python整理成了《漫画书》

前言 随着人工智能的发展&#xff0c;Python近两年也是大火&#xff0c;越来越多的人加入到Python学习大军&#xff0c;对于毫无基础的人该如何入门Python呢&#xff1f;小编这里整理了一套python编程零基础自学教程&#xff0c;清华大佬196小时讲完的&#xff0c;全程干货无废…...

有关Linux操作系统中僵尸进程与孤儿进程的理解

目录 一、僵尸进程&#xff08;僵死状态&#xff09;1.概念2.进程PID与退出码3.僵尸进程举例4.僵尸进程的危害5.僵尸进程的解决方案 二、孤儿进程1.概念2.特点3.孤儿进程解决僵尸进程 一、僵尸进程&#xff08;僵死状态&#xff09; 1.概念 僵死状态形象点说有点像是没死透的…...

Go语言实现依赖注入

文章目录 前言依赖注入是什么依赖注入的好处是什么结构图应用程序上下文接口上下文管理器暴露的功能使用示例最后 前言 你好&#xff0c;我是醉墨居士&#xff0c;欢迎来到我的博客&#xff0c;今天带领大伙使用Go语言实现依赖自动注入&#xff0c;我们不会使用其它的第三方库…...

不仅能防沉迷游戏的防沉迷软件(Python)

介绍 一个有那么一点功能但是又不太保险的防沉迷工具 我脑子进水了才会写这玩意儿 为了变强&#xff0c;我不择手段&#xff08;笑出zhu jiao 代码 好像没什么用的设定界面 # -*- coding: utf-8 -*- # Environment PyCharm # File_name login |User Pfolg # 2024/…...

数学建模--智能算法之鱼群算法

目录 核心原理 应用与实现 实现步骤 性能分析与改进 鱼群算法在解决哪些具体优化问题方面表现最佳&#xff1f; 如何根据不同的应用场景调整鱼群算法的参数设置以提高其性能&#xff1f; 鱼群算法与其他群体智能优化算法&#xff08;如遗传算法、粒子群优化&#xff09;…...

html+css+js前端作业qq音乐官网5个页面 带js

htmlcssjs前端作业qq音乐官网5个页面 带js 有轮播图&#xff0c;tab切换等多种效果 网页作品代码简单&#xff0c;可使用任意HTML编辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编…...

【mars3d】加载超图s3m模型说明

建议替换Cesium库&#xff0c;换成 超图版本Cesium mars3d mars3d-supermap &#xff0c;需要引入的资源为&#xff1a; "mars3d": ["Cesium-supermap/Widgets/widgets.css", //超图版本Cesium "Cesium-supermap/Cesium.js","mars3d/plu…...

LeetCode Hot100 二叉搜索树中第K小的元素

给定一个二叉搜索树的根节点 root &#xff0c;和一个整数 k &#xff0c;请你设计一个算法查找其中第 k 小的元素&#xff08;从 1 开始计数&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,1,4,null,2], k 1 输出&#xff1a;1示例 2&#xff1a; 输入&#xf…...

CBK-D5-安全测试与开发osg15、20、21

CBK-D5-安全测试与开发osg15、20、21 安全评估与测试 构建安全评估和测试方案 安全测试 旨在验证某项控制措施是否正常运行。 包括自动化扫描、工具辅助的渗透测试、破坏安全性的手动测试。 渗透测试可以每年开展一次,以最大限度地降低费用并减小业务中断的影响。 仅简…...

期权杠杆与期货杠杆的区别是什么?

期权与股指期货在杠杆性上展现出截然不同的特性&#xff0c;这些特性对投资者的策略选择具有深远影响。首先&#xff0c;股指期货采用保证金制度&#xff0c;其杠杆比例是恒定的&#xff0c;无论市场如何波动&#xff0c;投资者在月初设定的十倍杠杆到月尾仍保持不变。相比之下…...

数字人解决方案——音频驱动机器人

音频集成 机器人 标志着 人工智能&#xff08;AI&#xff09;。 想象一下&#xff0c;机器人可以通过视觉和听觉导航并与周围环境互动。音频驱动的机器人使这成为可能&#xff0c;提高了它们更高效、更直观地执行任务的能力。这一发展可能会影响到各个领域&#xff0c;包括家庭…...

Linux Tcp 连接 状态 检测 处理

查看不同状态的链接数 netstat -na | awk /^tcp/ {S[$NF]} END {for(a in S) print a, S[a]} 输出如下&#xff1a; TIME_WAIT 2 CLOSE_WAIT 2149 LISTEN 18 ESTABLISHED 214...

String respIson = objectMapper.writeValueAsString(response);

**一、代码解释** 这段代码的作用是使用ObjectMapper&#xff08;假设是 Jackson 的ObjectMapper&#xff09;将一个 Java 对象response转换为 JSON 格式的字符串。 1. ObjectMapper&#xff1a; 它是 Jackson 库中用于在 Java 对象和 JSON 之间进行序列化和反序列化的核心类。…...

git squash、merge 、 rebase

Git Merge、Rebase 和 Squash 之间的区别_git squash-CSDN博客...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

嵌入式常见 CPU 架构

架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集&#xff0c;单周期执行&#xff1b;低功耗、CIP 独立外设&#xff1b;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel&#xff08;原始…...