C++的类和对象(一)
目录
1、面向过程和面向对象初认识
2、为什么要有类
3、类的定义
类的两种定义方式
4、类的访问限定符
5、类的作用域
5.1 为什么要有作用域?
5.2类作用域
6、类的实例化
6.1类的实例化的定义
6.2类的实例化的实现
6.3经典面试题
7、类对象
7.1类对象的大小计算
7.2类对象的存储方式猜测
8、this指针
8.1this指针的介绍
8.2this指针的特性
1、面向过程和面向对象初认识
C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。
C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。
就拿外卖来举例:面向过程关注的就是:客户下单、店家接单、骑手送餐,这三个的过程
面向对象关注的就是:店家、骑手、客户,这三者之间的关系
注意:C++是基于面向对象,不是纯面向对象,也可以面向过程
2、为什么要有类
在C语言中已经有结构体了,为什么还要设计一个类出来呢?
在C语言中结构体只能用来定义变量,C++中对结构体进行了延伸,不仅可以用来定义变量还可以用来定义函数,而C++更喜欢用class来代替struct,也就是我们经常说的类,并且C++中类的功能可比C语言的结构体强大太多了。面向对象的三大特性:封装、继承、多态,都需要用到类来实现。
3、类的定义
class Student
{
public:void PrintInfo()//成员函数{cout << name << " " << sex << " " << age << endl;}char name[10];//成员变量char sex[3];int age;
};//和结构体一样最后也是要带上分号的
class为定义类的关键字;Student为类名;public为类的访问限定符,一共有三个,后面会讲到;{}里面为类的主体。
类中的元素称为类的成员:类中的数据称为类的属性或者成员变量; 类中的函数称为类的方法或者成员函数。
类的两种定义方式
1、声明和定义全部放到类体中,注意:如果成员函数在类中定义,可能会被编译器当成内联来处理
2、声明放到.h文件中,定义放到.cpp文件中,实现声明和定义的分离
我们一般在做项目的时候都比较建议采用第二种。
4、类的访问限定符
- public修饰的成员在类外可以直接被访问。
- protected和private修饰的成员在类外不能直接被访问。
- 访问权限作用范围从该访问限定符出现的位置开始直到下一个访问限定符出现时为止,如果没有下一个访问限定符的出现,那么就一直到 } 类结束。
- class的默认访问权限为private。
注意:访问限定符只在编译时有用,当数据保存到内存后,没有任何访问限定符的区别。
【经典面试题】
C++中struct和class的区别是什么?
C++是兼容C的,所以C++中的struct也可以当成结构体用,还可以用来定义类来使用,和class是一样的,但是struct定义的类的默认访问权限是public,class的默认访问权限是private。
5、类的作用域
5.1 为什么要有作用域?
作用域是为了避免变量名冲突和提供代码的组织结构而存在的。作用域定义了一个变量或函数在程序中的可见范围。例如,如果有两个变量具有相同的名称,但它们位于不同的作用域内,它们就不会相互干扰。作用域可以分为全局作用域和局部作用域,全局作用域表示变量或函数在程序中的任何位置都可以访问,而局部作用域表示变量或函数仅在限定的代码块或函数内可见。通过使用作用域,程序员可以更好地控制代码,并减少错误和混淆。
5.2类作用域
类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需要使用类名+ ::(作用域操作符)来指明成员属于哪个类域。
6、类的实例化
6.1类的实例化的定义
在C++中,类的实例化指的是使用类定义创建类的一个实例(也称为对象)。当定义一个类时,只是定义了类的结构和属性,但是没有实际的实例存在。为了使用类,必须先创建一个实例,然后可以使用该实例调用类中的方法和访问其属性。
6.2类的实例化的实现
class Student
{
public:void PrintInfo();
private:char name[10]; char sex[3];int age;
};int main()
{Student s;//实例化出一个对象s.PrintInfo();//用实例化出的对象访问类中的成员return 0;
}
实例化出的对象只能访问public修饰的成员,protected和private修饰的就访问不了。
和C语言的结构体一样也是用.进行访问。
一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类成员变量。
6.3经典面试题
了解完类的实例化后,看一下下面的题你是否能做出来
int age;//声明 or 定义?class Student
{
public:void PrintInfo();char name[10];char sex[3];int age;//声明 or 定义?
};
上面两个age一个在全局中,一个在类中,且都是在.h文件中,他们是声明还是定义?
当你编译的时候很可能会出现这样链接错误。
先要明白的概念
- 声明和定义的区别就在于开没开空间。
- 类在没有实例化之前是不占用空间的,只有实例化出对象了才占用空间
打个比方:类实例化出对象就像现实中使用建筑设计图盖房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象(房子)才能实际存储数据,占用物理空间
解答:
- 全局的age是定义, 类中的age是声明。
- 链接冲突是因为你是在.h中定义的,.h文件内容最终会在.cpp文件中展开,全局age是定义,当有多个.cpp文件同时编译完后在合成一个目标文件时,多个.cpp文件中都定义了同一个age就会造成冲突
要想解决这个问题可以在全局的age前面加上extern或者static
- extern是用于声明在另一个文件或模块中定义的变量或函数的关键字。当变量或函数声明为extern时,它告诉编译器该符号在其他地方定义,应该在链接期间解析。这允许函数和变量在程序中的多个文件或模块之间共享。
- 加static只在当前文件可见,链接属性不一样
7、类对象
7.1类对象的大小计算
// 类中既有成员变量,又有成员函数
class A1 {
public:void f1() {}
private:char c;int a;
};
//类中仅有成员变量
class A2
{
private:int a;
};
// 类中仅有成员函数
class A3 {
public:void f2() {}
};
//空类
class A4
{};
用sizeof计算他们的大小结果为sizeof(A1):8, sizeof(A2):4,sizeof(A3):1,sizeof(A4):1。
从结果可以看出类的大小的计算也是要遵守结构体内存对齐规则。并且成员函数是不占大小的,空类也是给了1字节的。
空类给这1字节的目的是为了占位,占位不存储实际数据,是为了表识对象的存在。
7.2类对象的存储方式猜测
1. 对象中包含类的各个成员
每个对象中都包含类的各个成员,但是这样缺点很明显,每个对象中成员变量是不同的,但是调用同一个函数,如果按照这种方式存储,当一个类创建多个对象时,每个对象中都会保存一份相同的代码,浪费空间。
2.代码只保存一份,在对象中保存存放代码的地址
这个方式在多态下会被采用
3.只保存成员变量,成员函数存放在公共的代码段
这种方式在编译连接时就会根据函数名去公共代码区找到函数的地址,call 函数的地址
8、this指针
8.1this指针的介绍
this指针是指向当前对象的指针。在C++中,每个对象都有一个指向自身的this指针,这样当有多个对象调用成员函数时就可以做到区分作用。
当在类的成员函数内部访问“非静态的”对象的成员变量或成员时,C++编译器会自动将该对象的地址赋给this指针,以便在函数内部可以通过this指针来访问对象的成员,这些操作对用户是隐藏的,即用户不需要来传递,编译器自动完成。
例如:
class Date
{
public:void Init(int year, int month, int day){this->_year = year;this->_month = month;this->_day = day;}void Print(){cout << this->_year << " " << this->_month << " " << this->_day << endl;}
private:int _year;int _month;int _day;
};int main()
{Date d1;Date d2;d1.Init(2023, 11, 10);d2.Init(2023, 11, 11);d1.Print();d2.Print();return 0;
}
在上述示例中,Init()和Print()两个成员函数内部都使用了this指针来访问成员变量,在传参的时候编译器隐藏了this指针,不需要用户手动去传的。
void Init(Date * const this, int year, int month, int day){this->_year = year;this->_month = month;this->_day = day;}
d1.Init(&d1, 2023, 11, 10);
上面的示例是一个伪代码。
实参和形参位置不能显示传递和接收this指针,但是可以在成员函数内部使用this指针。
8.2this指针的特性
- this指针的类型是*const的,const出现在星号右边,表示指针本身是常量,不能给this指针赋值即const pointer,non-const data。
- 只能在成员函数的内部使用。
- this指针本质上是成员函数的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参。但是对象中不存储this指针。
- this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递。
- this指针是存放在栈上的,因为它是个形参;但是不同的编译器可能会做优化,像VS编译器就是存放在寄存器上的,速度更快。
- this指针可以为空。例如下面例子就是可以正常运行的
class Date { public:void Print(){cout << this << endl;cout << "hello Date" << endl;} private:int _year;int _month;int _day; };int main() {Date* d1 = nullptr;d1->Print();//正常运行return 0; }
运行结果:
因为它没有对this指针进行使用操作,所以它是正常运行的。
但是下面这个代码就是运行崩溃了
class Date { public:void Print(){cout << _year << endl;} private:int _year;int _month;int _day; };int main() {Date* d1 = nullptr;d1->Print();//运行崩溃return 0; }
this指针为空,使用了一个空指针去访问成员变量,很明显是空指针问题,所以会运行崩溃。
这两份代码,一个对this指针进行了使用,一个没有,所以结果也会不同。
如果有写的不好或不对的地方欢迎大家指正。谢谢!!!
相关文章:

C++的类和对象(一)
目录 1、面向过程和面向对象初认识 2、为什么要有类 3、类的定义 类的两种定义方式 4、类的访问限定符 5、类的作用域 5.1 为什么要有作用域? 5.2类作用域 6、类的实例化 6.1类的实例化的定义 6.2类的实例化的实现 6.3经典面试题 7、类对象 7.1类对…...

基于单片机自动饮料混合机控制系统设计
**单片机设计介绍,基于单片机自动饮料混合机控制系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机自动饮料混合机控制系统设计是一个涉及多个领域的复杂项目,包括单片机技术、传感器技术…...

react-route-dom 实现简单的嵌套路由
最终效果 点击 to test1 点击to test2 > to test21 点击to test2 > to test22 代码如下 path: "page",element: <父组件 />,children: [{ path: "test1", element: <Test1 /> },{path: "test2",element: <Test2 />…...

万界星空科技灯具行业MES介绍
中国是LED照明产品最大的生产制造国,如今,我国初步形成了包括LED外延片的生产、LED芯片的制备、LED芯片的封装以及LED产品应用在内的较为完超为产业链,随着LED照明市场渗诱率的快速警升,LED下游应用市场将会越来越广阔。这也将推动…...
16进制字符串转字符串
一、浏览器上 function hexToUtf8(hexString) {const hexArray hexString.match(/.{1,2}/g) || [];const uint8Array new Uint8Array(hexArray.map(hex > parseInt(hex, 16)));const textDecoder new TextDecoder(GB2312); //可以切换字符编码return textDecoder.decode…...
pymysql.err.InternalError: (1054, “Unknown column ‘nan‘ in ‘field list‘“
记录在本地环境通过,然后在云环境,解决问题的过程; 最近两天遇到一个bug,具体就是在本地Pyhon环境运行成功,但是当放在云服务跑的时候,去屡屡报错,具体报错信息如下: pymysql.err.I…...
SQL 错误 [1476] [22012]: ORA-01476: 除数为 0
Oracle sql 语句 添加判断,如果分母为0,则查询结果为0,如果分母不为0,则返回查询结果 你可以使用条件表达式来实现这个要求。以下是一个示例的Oracle SQL查询语句,其中添加了判断条件来处理分母为0的情况:…...
go语言项目的目录结构
Golang 的项目目录结构并没有一个强制的标准,但社区中形成了一些共识和最佳实践,以便更好地组织和管理代码。以下是一个典型的 Golang 项目目录结构示例: /myproject ├── /cmd | ├── /app | | └── main.go | …...
Android : DataBinding 简化开发 简单应用
1.导包 ViewModel 用于观察数据 // 使用androidx版本库 ViewModelProviders implementation androidx.lifecycle:lifecycle-extensions:2.1.0-alpha032.在build.gradle 添加 在android 代码块中添加 复制后点更新(Sync Now) android{...// 步骤1.开启…...

计算机网络:应用层(下篇)
文章目录 前言一 、电子邮件(Email)1.邮件服务器2.SMTP[RFC 2821]3.邮件报文格式4.邮件访问协议 二、DNS(域名系统)1.DNS的历史2.DNS总体思路和目标(1)问题1:DNS名字空间(2ÿ…...

干货分享 | TSMaster小程序启动和停止的自动化控制流程
在实际应用场景中,用户常常需要按一定逻辑和时序来控制TSMaster内置功能模块的启动和停止,TSMaster软件内置有C/Python小程序和图形程序,开发者可以通过编程对这些模块的运行进行精确控制。本文将重点和大家分享一下如何通过C代码来控制TSMas…...

AI视频智能分析识别技术的发展与EasyCVR智慧安防视频监控方案
随着科技的不断进步,基于AI神经网络的视频智能分析技术已经成为了当今社会的一个重要组成部分。这项技术通过利用计算机视觉和深度学习等技术,实现对视频数据的智能分析和处理,从而为各个领域提供了广泛的应用。今天我们就来介绍下视频智能分…...

外包干了2个月,技术倒退2年。。。
先说一下自己的情况,本科生,20年通过校招进入深圳某软件公司,干了接近4年的功能测试,今年国庆,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…...

书-用数组存储高于60低于70的人单独存起来
#include<stdio.h> # define N 10 //书-用数组存储高于60低于70的人单独存起来 int main(){float s[N]{68.2,62.3,63.4,34.5,45.6,56.7,67.8,78.9,89.0,100};int i;float diyu[100];int j0;for(i0;i<N;i){if(s[i]>60 && s[i]<70)diyu[j]s[i];//这里的范…...

三、DVP摄像头调试笔记(图片成像质量微调整,非ISP)
说明:当前调试仅仅用来测试和熟悉部分摄像头寄存器模式 一、图片成像方向控制,基本每个摄像头都会有上下左右翻转寄存器 正向图片 反向图片 二、设置成像数据成各种颜色,(黑白/原彩/黄色等等) 在寄存器书册描述中…...

Linux--程序地址空间
📘北尘_:个人主页 🌎个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上,不忘来时的初心 [TOC](文章目录) 一、程序地址空间回顾 我们在讲C语言的时候,老师给大家画过这样的空间布局…...

【超全】React学习笔记 下:路由与Redux状态管理
React学习笔记 React系列笔记学习 上篇笔记地址:【超全】React学习笔记 上:基础使用与脚手架 中篇笔记地址:【超全】React学习笔记 中:进阶语法与原理机制 React路由概念与理解使用 1. 引入 React路由是构建单页面应用(SPA, Sin…...

matplotlib学习
显示两个figure 坐标上刻度修改 plt.xlim() 下标范围 plt.xticks() 替换新的下标 图例显示 散点图 subplot多合一显示...

【网络安全】-安全常见术语介绍
文章目录 介绍1. 防火墙(Firewall)定义通俗解释 2. 恶意软件(Malware)定义通俗解释 3. 加密(Encryption)定义通俗解释 4. 多因素认证(Multi-Factor Authentication,MFA)定…...

C语言给定数字0-9各若干个。你可以以任意顺序排列这些数字,但必须全部使用。目标是使得最后得到的数尽可能小(注意0不能做首位)
这个题目要求的输出是一串数字!!! 不是下面:输入在一行中给出 10 个非负整数,顺序表示我们拥有数字 0、数字 1、……数字 9 的个数。整数间用一个空格分隔。10 个数字的总个数不超过 50,且至少拥有 1 个非…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...

Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...

Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...

《信号与系统》第 6 章 信号与系统的时域和频域特性
目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...
Qt Quick Controls模块功能及架构
Qt Quick Controls是Qt Quick的一个附加模块,提供了一套用于构建完整用户界面的UI控件。在Qt 6.0中,这个模块经历了重大重构和改进。 一、主要功能和特点 1. 架构重构 完全重写了底层架构,与Qt Quick更紧密集成 移除了对Qt Widgets的依赖&…...