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

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、类的访问限定符

  1. public修饰的成员在类外可以直接被访问。
  2. protected和private修饰的成员在类外不能直接被访问。
  3. 访问权限作用范围从该访问限定符出现的位置开始直到下一个访问限定符出现时为止,如果没有下一个访问限定符的出现,那么就一直到 } 类结束。
  4. 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文件中,他们是声明还是定义?

当你编译的时候很可能会出现这样链接错误。

 先要明白的概念

  1. 声明和定义的区别就在于开没开空间。
  2. 类在没有实例化之前是不占用空间的,只有实例化出对象了才占用空间

打个比方:类实例化出对象就像现实中使用建筑设计图盖房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象(房子)才能实际存储数据,占用物理空间

解答:

  • 全局的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 为什么要有作用域&#xff1f; 5.2类作用域 6、类的实例化 6.1类的实例化的定义 6.2类的实例化的实现 6.3经典面试题 7、类对象 7.1类对…...

基于单片机自动饮料混合机控制系统设计

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

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照明产品最大的生产制造国&#xff0c;如今&#xff0c;我国初步形成了包括LED外延片的生产、LED芯片的制备、LED芯片的封装以及LED产品应用在内的较为完超为产业链&#xff0c;随着LED照明市场渗诱率的快速警升&#xff0c;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‘“

记录在本地环境通过&#xff0c;然后在云环境&#xff0c;解决问题的过程&#xff1b; 最近两天遇到一个bug&#xff0c;具体就是在本地Pyhon环境运行成功&#xff0c;但是当放在云服务跑的时候&#xff0c;去屡屡报错&#xff0c;具体报错信息如下&#xff1a; pymysql.err.I…...

SQL 错误 [1476] [22012]: ORA-01476: 除数为 0

Oracle sql 语句 添加判断&#xff0c;如果分母为0&#xff0c;则查询结果为0&#xff0c;如果分母不为0&#xff0c;则返回查询结果 你可以使用条件表达式来实现这个要求。以下是一个示例的Oracle SQL查询语句&#xff0c;其中添加了判断条件来处理分母为0的情况&#xff1a;…...

go语言项目的目录结构

Golang 的项目目录结构并没有一个强制的标准&#xff0c;但社区中形成了一些共识和最佳实践&#xff0c;以便更好地组织和管理代码。以下是一个典型的 Golang 项目目录结构示例&#xff1a; /myproject ├── /cmd | ├── /app | | └── main.go | …...

Android : DataBinding 简化开发 简单应用

1.导包 ViewModel 用于观察数据 // 使用androidx版本库 ViewModelProviders implementation androidx.lifecycle:lifecycle-extensions:2.1.0-alpha032.在build.gradle 添加 在android 代码块中添加 复制后点更新&#xff08;Sync Now&#xff09; android{...// 步骤1.开启…...

计算机网络:应用层(下篇)

文章目录 前言一 、电子邮件&#xff08;Email&#xff09;1.邮件服务器2.SMTP[RFC 2821]3.邮件报文格式4.邮件访问协议 二、DNS&#xff08;域名系统&#xff09;1.DNS的历史2.DNS总体思路和目标&#xff08;1&#xff09;问题1&#xff1a;DNS名字空间&#xff08;2&#xff…...

干货分享 | TSMaster小程序启动和停止的自动化控制流程

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

AI视频智能分析识别技术的发展与EasyCVR智慧安防视频监控方案

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

外包干了2个月,技术倒退2年。。。

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

书-用数组存储高于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)

说明&#xff1a;当前调试仅仅用来测试和熟悉部分摄像头寄存器模式 一、图片成像方向控制&#xff0c;基本每个摄像头都会有上下左右翻转寄存器 正向图片 反向图片 二、设置成像数据成各种颜色&#xff0c;&#xff08;黑白/原彩/黄色等等&#xff09; 在寄存器书册描述中…...

Linux--程序地址空间

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

【超全】React学习笔记 下:路由与Redux状态管理

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

matplotlib学习

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

【网络安全】-安全常见术语介绍

文章目录 介绍1. 防火墙&#xff08;Firewall&#xff09;定义通俗解释 2. 恶意软件&#xff08;Malware&#xff09;定义通俗解释 3. 加密&#xff08;Encryption&#xff09;定义通俗解释 4. 多因素认证&#xff08;Multi-Factor Authentication&#xff0c;MFA&#xff09;定…...

C语言给定数字0-9各若干个。你可以以任意顺序排列这些数字,但必须全部使用。目标是使得最后得到的数尽可能小(注意0不能做首位)

这个题目要求的输出是一串数字&#xff01;&#xff01;&#xff01; 不是下面&#xff1a;输入在一行中给出 10 个非负整数&#xff0c;顺序表示我们拥有数字 0、数字 1、……数字 9 的个数。整数间用一个空格分隔。10 个数字的总个数不超过 50&#xff0c;且至少拥有 1 个非…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

深入理解Optional:处理空指针异常

1. 使用Optional处理可能为空的集合 在Java开发中&#xff0c;集合判空是一个常见但容易出错的场景。传统方式虽然可行&#xff0c;但存在一些潜在问题&#xff1a; // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...

医疗AI模型可解释性编程研究:基于SHAP、LIME与Anchor

1 医疗树模型与可解释人工智能基础 医疗领域的人工智能应用正迅速从理论研究转向临床实践,在这一过程中,模型可解释性已成为确保AI系统被医疗专业人员接受和信任的关键因素。基于树模型的集成算法(如RandomForest、XGBoost、LightGBM)因其卓越的预测性能和相对良好的解释性…...

(12)-Fiddler抓包-Fiddler设置IOS手机抓包

1.简介 Fiddler不但能截获各种浏览器发出的 HTTP 请求&#xff0c;也可以截获各种智能手机发出的HTTP/ HTTPS 请求。 Fiddler 能捕获Android 和 Windows Phone 等设备发出的 HTTP/HTTPS 请求。同理也可以截获iOS设备发出的请求&#xff0c;比如 iPhone、iPad 和 MacBook 等苹…...

统计按位或能得到最大值的子集数目

我们先来看题目描述&#xff1a; 给你一个整数数组 nums &#xff0c;请你找出 nums 子集 按位或 可能得到的 最大值 &#xff0c;并返回按位或能得到最大值的 不同非空子集的数目 。 如果数组 a 可以由数组 b 删除一些元素&#xff08;或不删除&#xff09;得到&#xff0c;…...

Heygem50系显卡合成的视频声音杂音模糊解决方案

如果你在使用50系显卡有杂音的情况&#xff0c;可能还是官方适配问题&#xff0c;可以使用以下方案进行解决&#xff1a; 方案一&#xff1a;剪映替换音色&#xff08;简单适合普通玩家&#xff09; 使用剪映换音色即可&#xff0c;口型还是对上的&#xff0c;没有剪映vip的&…...