【C++】初识面向对象:类与对象详解
C++语法 | 相关知识点 | 可以通过点击 | 以下链接进行学习 | 一起加油! |
---|---|---|---|---|
命名空间 | 缺省参数与函数重载 | C++相关特性 |
本章将介绍C++中一个重要的概念——类。通过类,我们可以类中定义成员变量和成员函数,实现模块化封装,从而构建更加抽象和复杂的工程。
🌈个人主页:是店小二呀
🌈C语言笔记专栏:C语言笔记
🌈C++笔记专栏: C++笔记
🌈初阶数据结构笔记专栏: 初阶数据结构笔记
🌈Linux笔记专栏: Linux笔记
🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅
文章目录
- 一、面向过程与面向对象初步认识
- 二、类的引入
- 2.1 定义概念
- 2.2 类的定义
- 2.3 成员变量命令规则
- 三、类的访问限定符及封装
- 3.1 访问限定符
- 3.1.1 class与struct区别
- 3.2 封装
- 四、类的作用域(类域)
- 五、类的实例化
- 六、类对象模型
- 6.1 计算类对象的大小
- 6.2 类对象的存储方式猜测
- 七、this指针
- 7.1 this指针的引入
- 7.2 this指针的特性
- 八、面试题
一、面向过程与面向对象初步认识
- C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题
- C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,依靠对象之间的交互完成
二、类的引入
2.1 定义概念
定义是编程中的一项基础操作,涉及到为特定数据分配到一个名称和存储位置。不能通过是否赋值去判断是否存在定义,而是通过是否为其开辟空间。
C语言结构体中只能定义变量struct S s1 ={"Alice", c}
; 在C++中结构体内不仅可以定义变量,也可也定义函数。现在以C++方式实现 ,struct
可以定义变量及其函数,但是更喜欢使用class
代替struct
(类替代结构体)
struct Stack
{void Init(size_tt capacity){//一系列操作}new_capacity=capacity;size=10;
};
2.2 类的定义
class className
{//类体:一般由成员函数和成员变量组成
};//同结构体一般,需要添加分号
class
为定义类的关键字,ClassName
为类的名字,{}
中为类的主体,注意类定义结束时后面分号不能省略。
类体中内容称为类的成员,其中类的成员:1.类中的变量称为类的属性或成员变量2.类中的函称为类的方法或者成员函数
类的两种定义方式:
- 声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理。
- 类声明放在.h文件中,成员函数定义放在
.cpp
文件中,注意:成员函数名前需要加类名::
一般情况下,更加期望采用第二种方式。为了方便演示将采用第一种,大家在后序工作中尽量使用第二种方式,体现了面对对象编程的封装特性,提高代码的可维护性。
2.3 成员变量命令规则
由于在使用类过程中,难免会遇到成员变量与函数参数名称相同导致混淆。比如:这里如何去区分year属于成员变量还是函数参数呢?
class Date
{
public:void Init(int year){year = year;}
private:int year;
};
对此我们需要通过一些方式去区分,这里建议成员变量前面加个_
。当然其他方式也是可以的,主要看公司要求统一
_year = year 这样子就很容易区分啦
三、类的访问限定符及封装
3.1 访问限定符
C++实现封装的方式:用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用
【访问限定符】:
- public修饰成员可以在类外直接被访问(权限公开)
- protected和private修饰成员在类外不能直接被访问
- protected和private在现阶段作用相同的,在继承章节会有区分
- 访问权限作用域是从访问限定符出现位置到下一个访问限定符出现为止,如果没有出现新的访问限定符,作用域到
}
,即类结束。 - class的默认访问权限为private,
struct
的默认访问权限为public(由于struct
需要兼容C)
访问限定符只在编译时期有效,当数据映射到内存后,没有任何访问限定符的区别
class Data
{public:void Print(){cout << _year << endl;}
private:int _year = 100;
};
3.1.1 class与struct区别
由于C++兼容C,在C++中struct
可以当成结构体使用,另外struct
同class
可以定义类。通过访问限定符从中我们得出了class
与struct
区别在于默认权限不同。
区别是struct
定义的类默认访问权限是public
,class
定义的类默认访问权限是private
。除此之外在继承和模板参数列表位置上,struct
和class
也有区别。
3.2 封装
【面试题】:面向对象的三大特性:封装、继承、多态
封装:将数据和操作数据方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。封装本质上是一种管理,让用户更方便使用类。比如对于电脑这样子一个复杂的设备。
对于计算机使用者而言,不用关心内部核心部件,比如主板上线路是如何布局的,CPU内部是如何设计的等,用户只需要知道,怎么开机、怎么通过键盘和鼠标与计算机进行交互即可。因此计算机厂商在出厂时,在外部套上壳子,将内部实现细节隐藏起来,仅仅对外提供开关机、鼠标以及键盘插孔等,让用户可以与计算机进行交互即可
在C++语言中实现封装,可以通过类将数据以及操作数据的方法进行有机结合,通过访问权限来隐藏对象内部实现细节,控制哪些方法可以在类外部直接被使用。
四、类的作用域(类域)
类定义了新的作用域,名为类域。同命名空间类般能解决命名冲突。类的所有成员都在类的作用域中。在类体外定义成员时,需要使用 ::
作用域操作符指明成员属于哪个类域进行优先查找。
//这里PrintPersonInfo函数属于Person类域
void Person:: PrintPersonInfo()
{cout<<_name<<_sex<<_age<<endl;
}
五、类的实例化
类是对对象进行描述,虽然限定了类有那些成员,但是没有实际分配空间。使类类型进行创建对象过称为类的实例化,如果出现没有对类进行实例化操作,而私自调用类中成员变量会报错,如:Person._age = 10
。并且其中一个类可以实例化出多个对象,并且占用实际的物理空间用于存储成员变量。
打个比方:类实例化出对象就像现实中使用建筑设计图建造出房子,类就像设计图。
六、类对象模型
6.1 计算类对象的大小
class A
{public:void PrintA(){cout<<_a<<endl;}private:char _a;
};
【问题】:类中既可以有成员变量,又可以有成员函数,那么一个类的对象中包含了什么?如何计算一个类的大小?
6.2 类对象的存储方式猜测
- 对象中包含类的各个成员
【缺陷】:每个对象的成员变量不同,但是调用同一份函数。若当一个类创建多个对象时,每个对象中都会保存一份代码,相同代码保存多次,浪费空间
- 代码只保存一份,在对象中保存存放代码的地址
- 只保存成员变量,成员函数存放在公共的代码段
面对以上三种,对于类对于对象的存储设计的猜测,可以通过多组测试类中对象的大小。
结论:一个类的大小,实际就是该类中成员变量
之和(涉及内存对齐)。这里采用第三种存储内存的设计。不将成员函数算入类内存中,而是将类成员函数存储在公共代码区
空类比较特殊,编译器给空类一个字节来唯一标识这个类的对象,表示这个对象存在过,可能有成员函数。
七、this指针
7.1 this指针的引入
class Date
{
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()
{Date d1, d2;d1.Init(2022, 1, 11);d2.Init(2022, 1, 12);d1.Print();d2.Print();return 0;
}
面对上面代码,我们思考个问题:Date类中有Init
与Print
两个成员函数,对于函数体没有关于不同对象的区分,当不同对象调用函数时,该函数如何知道应该设置或打印d1
对象,而不是d2
对象呢?
C++中通过引入this指针解决该问题,即:C++编译器给每个非静态的成员函数增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。
7.2 this指针的特性
this
指针的类型:类类型*const
,既成员函数中,不能给this
赋值this
指针不能显示在实参和形参的位置,只能在成员函数的内部使用this
指针本质上是成员函数的形参,当对象调用成员函数时,将对象地址作为实参传递给this
形参,所以对象中不存储this
指针this
指针是成员函数第一个隐含的指针形参,将对象的地址作为实参传递,对此函数的参数个数为n+1
个,一般情况由编译器通过exc
寄存器,不需要用户传递
八、面试题
1.结构体如何对齐?
在结构体中,成员的内存对齐是由编译器决定的,通常会按照平台和编译器的规则进行对齐
2.为什么内存对齐
内存对齐是为了提高内存访问效率和系统性能的。当数据结构按照特定的字节边界对齐时,处理器可以更有效地读取和写入内存,减少了内存访问的次数和时间。这样可以提高数据读取速度,减少内存碎片化,并且可以避免一些硬件平台上的异常行为。
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
3.如何让结构体按照指定的对齐参数进行对齐?能否按照3、4、即任意字节对齐?
C语言中,可以使用#pragma pack
指令:
//这里n是指定的对齐参数,可以是任意字节,比如3或4
#pragma pack(n)
struct YourStruct { // 结构体成员 };
4.什么是大小端
大小端(Endian
)是指在存储多字节数据时,字节的排列顺序。
- 大端字节序(
Big-endian
): 高位字节存储在低地址,低位字节存储在高地址。 - 小端字节序(
Little-endian
): 低位字节存储在低地址,高位字节存储在高地址。
5.如何测试某台机器是大端还是小端
程序创建一个整数变量(num
),然后通过将其地址强制转换为字符指针,检查存储在该地址的第一个字节的值,从而确定字节序。
6.没有遇到过要考虑大小端的场景
- 数据序列化和反序列化: 在网络通信、文件读写等情境中,需要确保数据在不同系统之间正确地序列化和反序列化。
- 硬件寄存器访问: 与硬件直接交互时,需要按照硬件的大小端规则进行数据存取。
- 跨平台开发: 在开发跨平台应用时,需要谨慎处理大小端问题,以确保在不同系统上的一致性。
了解大小端是确保不同系统之间数据正确传递和解释的关键因素。
7.this指针可以为空吗?
this
指针指向调用成员函数的对象,因此在对象存在时,this
指针不会为空。
在C++11中,可以在空对象(即没有分配内存的对象,匿名对象)上调用成员函数,但这并不意味着this
指针是NULL
。相反,编译器会将空对象的地址传递给this
指针,但是在成员函数内部要特别小心处理这种情况,以避免潜在的未定义行为。
8.this指针存在哪里
虽然this
被const
修饰,但是不存储在常量区。C++中cosnt
修饰变量本身不存储在常量区,而是在栈上。this
作为一个形参,有些编译可能用寄存器存储。可能频繁的使用this
不如放在寄存器上。
9.关于两道题目
// 1.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行
class A
{
public:void Print(){cout << "Print()" << endl;}private:int _a;
};
int main()
{A* p = nullptr;p->Print();return 0;
}
// 1.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行
class A
{public:void PrintA(){cout<<_a<<endl;}private:int _a;
};
int main()
{A* p = nullptr;p->PrintA();return 0;
}
过程解析:C++标准允许对空指针的成员函数进行调用,只要成员函数没有访问成员数据(如 _a
),这不会导致崩溃
以上就是本篇文章的所有内容,在此感谢大家的观看!这里是店小二呀C++笔记,希望对你在学习C++语言旅途中有所帮助!
相关文章:

【C++】初识面向对象:类与对象详解
C语法相关知识点可以通过点击以下链接进行学习一起加油!命名空间缺省参数与函数重载C相关特性 本章将介绍C中一个重要的概念——类。通过类,我们可以类中定义成员变量和成员函数,实现模块化封装,从而构建更加抽象和复杂的工程。 &…...

知识图谱学习总结
1 知识图谱的介绍 知识图谱,是结构化的语义知识库,用于迅速描述物理世界中的概念及其相互关系,通过知识图谱能够将Web上的信息、数据以及链接关系聚集为知识,使信息资源更易于计算、理解以及评价,并能实现知识的快速响…...
2021-10-23 51单片机LED1-8按秒递增闪烁
缘由51单片机,八个LED灯按LED1亮1s灭1s,LED1亮2s 灭2s以此类推的方式亮灭-编程语言-CSDN问答 #include "REG52.h" sbit K1 P1^0; sbit K2 P1^1; sbit K3 P1^2; sbit K4 P1^3; sbit P1_0P2^0; sbit P1_1P2^1; sbit P1_2P2^2; sbit P1_3P2^3; sbit P1_…...

在Linux中宏观的看待线程
线程一旦被创建,几乎所有的资源都是被所有的线程共享的。线程也一定要有自己私有的资源,什么样的资源应该是线程私有的? 1.PCB属性私有 2.要有一定的私有上下文结构 3.每个线程都要有独立的栈结构 ps -aL ##1. Linux线程概念 ###什么是线程…...
提示libfakeroot.so或libfakeroot-sysv.so出错处理方法
在RK3588 Buildroot SDK里面,uboot和kernel使用的是prebuild目录下的交叉编译链,而buildroot和APP编译则使用Buildroot生成的交叉编译链来编译(如:位于buildroot/output/rockchip_rk3588/host目录为交叉编译工具链目录)…...

【计算机网络】什么是socket编程?以及相关接口详解
💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃个人主页 :阿然成长日记 …...

LeetCode.19.删除链表的倒数第n个节点
题目描述: 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点 输入输出实例: 思路:这道题目我们可以用双指针来做,让first和second指针之间的距离为n1,然后我们first和second指针…...
vue-cesium
vue-cesium: Vue 3.x components for CesiumJS. cesium 文档中文版 ArcGisMapServerImageryProvider - Cesium Documentation all参考 https://juejin.cn/post/7258119652726341669 cesium官网 Cesium Sandcastle...
《npm 学习过程中遇到的诸多问题》
npm 开发 1.开发过程中难免会使用到npm ,进行安装第三方包 遇到的问题 match 报错:npm i报错npm ERR! Cannot read property match of undefined 可以尝试清除本地的package-log.json 文件,再试试...

CentOS 介绍
引出 Linux 系统内核与 Linux 发行套件系统的区别? Linux 系统内核指的是一个由 Linus Torvalds(Linux之父,内核主要开发者)负责维护,提供硬件抽象层、磁盘、文件系统控制及多任务功能的系统核心程序。 Linux 发行套…...

模拟面试题1
目录 一、JVM的内存结构? 二、类加载器分为哪几类? 三、讲一下双亲委派机制 为什么要有双亲委派机制? 那你知道有违反双亲委派的例子吗? 四、IO 有哪些类型? 五、Spring Boot启动机制 六、Spring Boot的可执行…...

CTFHUB-web-RCE-综合过滤练习
开启题目 查看网页源代码发现这次网页对 | 、 && 、 || 、 \ 、 / 、; ,都进行了过滤处理 发现换行符 %0a 和回车符 %0d 可以进行测试,在 URL 后面拼接访问 127.0.0.1%0als 用 ls flag_is_here 查看 flag 文件中的内容,发现回显为空…...

Leetcode75-7 除自身以外数组的乘积
没做出来 本来的思路是遍历一遍得到所有乘积和然后除就行 但是题目不能用除法 答案的思路 for(int i0;i<n;i) //最终每个元素其左右乘积进行相乘得出结果{res[i]*left; //乘以其左边的乘积left*nums[i];res[n-1-i]*right; //乘以其右边的乘积right*nums[n-1-i]…...

AI绘画工具介绍:以新奇角度分析与探索AI绘画艺术与技术的交汇点
目录 前言 一、AI绘画工具的前沿技术 1.1 深度学习的进化 1.2 GANs的创新应用 1.3 风格迁移的多样化 1.4 交互式AI绘画的智能化 二、艺术与技术的交汇点 2.1 艺术创作的普及化 2.2 艺术风格的创新 2.3 艺术与科技的深度融合 三、新颖的思考角度 3.1 AI作为艺术创作…...

基于Springboot + Vue的宿舍管理系统
前言 文末获取源码数据库 感兴趣的可以先收藏起来,需要学编程的可以给我留言咨询,希望帮助更多的人 精彩专栏推荐订阅 不然下次找不到哟 Java精品毕设原创实战项目 作者的B站地址:程序员云翼的个人空间-程序员云翼个人主页-哔哩哔哩视频 csd…...

CTFHUB-web-RCE-eval执行
开启题目 查看源码发现直接用蚁剑连接就可以,连接之后发现成功了...
Oracle DBA常用 sql
文章目录 一、基础环境二、常用 sql三、参考资料 版权声明:本文为CSDN博主「杨群」的原创文章,遵循 CC 4.0 BY-SA版权协议,于2023年7月6日首发于CSDN,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.n…...

MindSearch:AI 时代的“思考型”搜索引擎
随着AI技术的飞速发展,搜索引擎领域也迎来了新的变革。继 OpenAI 发布 SearchGPT 之后,国内也涌现出一批优秀的AI搜索引擎,其中,由中科大和上海人工智能实验室联合研发的 MindSearch(思索)尤为引人注目。这…...
机器学习练手(四):基于SVM 的肥胖风险分类
总结:本文为和鲸python 机器学习原理与实践闯关训练营资料整理而来,加入了自己的理解(by GPT4o) 原活动链接 原作者:vgbhfive,多年风控引擎研发及金融模型开发经验,现任某公司风控研发工程师&…...
AutoGPT项目实操总结
AutoGPT项目介绍 AutoGPT是一个基于GPT-4的开源项目,旨在简化用户与语言模型的交互过程,使文本生成和信息收集更轻松、更高效。它具备互联网搜索、长短期记忆管理、调用大模型进行文本生成、存储和总结文件等能力,并且可以通过插件扩展功能与…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...

Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向
在人工智能技术呈指数级发展的当下,大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性,吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型,成为释放其巨大潜力的关键所在&…...

快速排序算法改进:随机快排-荷兰国旗划分详解
随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...