【C++】初识面向对象:类与对象详解

news2024/11/19 1:48:31

在这里插入图片描述

C++语法相关知识点可以通过点击以下链接进行学习一起加油!
命名空间缺省参数与函数重载C++相关特性

本章将介绍C++中一个重要的概念——类。通过类,我们可以类中定义成员变量和成员函数,实现模块化封装,从而构建更加抽象和复杂的工程。

请添加图片描述
Alt
🌈个人主页:是店小二呀
🌈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.类中的函称为类的方法或者成员函数

类的两种定义方式:

  1. 声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理

在这里插入图片描述

  1. 类声明放在.h文件中,成员函数定义放在.cpp文件中,注意:成员函数名前需要加类名::

在这里插入图片描述

一般情况下,更加期望采用第二种方式。为了方便演示将采用第一种,大家在后序工作中尽量使用第二种方式,体现了面对对象编程的封装特性,提高代码的可维护性。

2.3 成员变量命令规则

由于在使用类过程中,难免会遇到成员变量与函数参数名称相同导致混淆。比如:这里如何去区分year属于成员变量还是函数参数呢

class Date
{
public:
    void Init(int year)
    {
         year = year;
    }
private:
	int year;
};

对此我们需要通过一些方式去区分,这里建议成员变量前面加个_当然其他方式也是可以的,主要看公司要求统一

_year = year 这样子就很容易区分啦

三、类的访问限定符及封装

3.1 访问限定符

C++实现封装的方式:用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用

在这里插入图片描述

访问限定符】:

  1. public修饰成员可以在类外直接被访问(权限公开)
  2. protected和private修饰成员在类外不能直接被访问
  3. protected和private在现阶段作用相同的,在继承章节会有区分
  4. 访问权限作用域是从访问限定符出现位置到下一个访问限定符出现为止,如果没有出现新的访问限定符,作用域到},即类结束。
  5. 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可以当成结构体使用,另外structclass可以定义类。通过访问限定符从中我们得出了classstruct区别在于默认权限不同。

区别是struct定义的类默认访问权限是publicclass定义的类默认访问权限是private。除此之外在继承和模板参数列表位置上,structclass也有区别。

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 类对象的存储方式猜测

  1. 对象中包含类的各个成员

在这里插入图片描述

缺陷】:每个对象的成员变量不同,但是调用同一份函数。若当一个类创建多个对象时,每个对象中都会保存一份代码,相同代码保存多次,浪费空间

  1. 代码只保存一份,在对象中保存存放代码的地址

在这里插入图片描述

  1. 只保存成员变量,成员函数存放在公共的代码段

在这里插入图片描述

在这里插入图片描述

面对以上三种,对于类对于对象的存储设计的猜测,可以通过多组测试类中对象的大小。

在这里插入图片描述

结论:一个类的大小,实际就是该类中成员变量之和(涉及内存对齐)。这里采用第三种存储内存的设计。不将成员函数算入类内存中,而是将类成员函数存储在公共代码区

空类比较特殊,编译器给空类一个字节来唯一标识这个类的对象,表示这个对象存在过,可能有成员函数。

七、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类中有InitPrint两个成员函数,对于函数体没有关于不同对象的区分,当不同对象调用函数时,该函数如何知道应该设置或打印d1对象,而不是d2对象呢?

C++中通过引入this指针解决该问题,即:C++编译器给每个非静态的成员函数增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。

在这里插入图片描述

7.2 this指针的特性

  1. this指针的类型:类类型*const ,既成员函数中,不能给this赋值
  2. this指针不能显示在实参和形参的位置,只能在成员函数的内部使用
  3. this指针本质上是成员函数的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参,所以对象中不存储this指针
  4. 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.没有遇到过要考虑大小端的场景

  1. 数据序列化和反序列化: 在网络通信、文件读写等情境中,需要确保数据在不同系统之间正确地序列化和反序列化。
  2. 硬件寄存器访问: 与硬件直接交互时,需要按照硬件的大小端规则进行数据存取。
  3. 跨平台开发: 在开发跨平台应用时,需要谨慎处理大小端问题,以确保在不同系统上的一致性。

了解大小端是确保不同系统之间数据正确传递和解释的关键因素。

7.this指针可以为空吗?

this指针指向调用成员函数的对象,因此在对象存在时,this指针不会为空。

在C++11中,可以在空对象(即没有分配内存的对象,匿名对象)上调用成员函数,但这并不意味着this指针是NULL。相反,编译器会将空对象的地址传递给this指针,但是在成员函数内部要特别小心处理这种情况,以避免潜在的未定义行为。

8.this指针存在哪里

虽然thisconst修饰,但是不存储在常量区。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++语言旅途中有所帮助!
请添加图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springboot约车APP-计算机毕业设计源码96773

基于Spring Boot的约车APP设计与实现 摘要 本文基于Spring Boot框架设计并实现了一款约车APP&#xff0c;旨在为用户提供便捷的出行服务。通过后端Spring Boot框架和前端交互界面的设计&#xff0c;实现了用户快速叫车、实时定位、路线规划等功能。系统结合了高效的后端处理和直…

LVS 调度器 nat和DR模式

lvs-nat 修改请求报文的目标IP,多目标IP的DNAT 配置网络 LVS主机 注意网卡的顺序 &#xff08;nat和主机模式&#xff09; [rootlvs ~]# cat /etc/NetworkManager/system-connections/ens160.nmconnection [connection] idens160 typeethernet interface-nameens160 ​ [ip…

[Unity]在场景中随机生成不同位置且不重叠的物体

1.前言 最近任务需要用到Unity在场景中随机生成物体&#xff0c;且这些物体不能重叠&#xff0c;简单记录一下。 参考资料:How to ensure that spawned targets do not overlap ? 2.结果与代码 结果如下所示&#xff1a; 代码如下所示&#xff1a; using System.Collec…

阿一网络安全学院学员作业——XSS DOM 型靶场

第一题 第二题 查看源码发现这里引用的 angular 框架 body 头为 ng-app 搜索文献得知 angular 框架可以将 {{x}} 内部执行函数 试验得知 angular 可以执行 {{ }} 内部函数 那么我们注入代码 {{alert()}} 调用了 search 解释器 那么我们注入的 search 是 先闭合 ”…

详解Xilinx FPGA高速串行收发器GTX/GTP(3)--GTX的时钟架构

目录 1、参考时钟 2、时钟方案 2.1、单个外部参考时钟驱动单个QUAD中的多个transceiver 2.2、单个外部参考时钟驱动多个QUAD中的多个transceiver 2.3、同一个Quad中,多个GTX Transceiver使用多个参考时钟 2.4、不同Quad中,多个GTX Transceiver 使用多个参考时钟 3、QP…

开源免费前端地图开发组件xdh-map

xdh-map是一个基于Openlayers的地图应用Vue组件&#xff0c;具有多方面的功能和特点。以下是对xdh-map的详细介绍&#xff1a; 一、功能与特性 内置多种地图瓦片&#xff1a;xdh-map内置了百度、高德、天地图等地图瓦片&#xff0c;使得开发者可以方便地在应用中集成多种地图…

机器视觉24

block使用流程 初始化工具 初始化相机 拍照事件 保存图片事件 读取图片事件 拍照完成后事件 检测事件 跳转block设置页面 曝光设置 关闭相机 保存图片封装方法 读取图片封装方法 //Block 设置窗体 实时显示 扩展 因为VP中有很多工具 所以在VS中使用时 可能频繁的导入工具…

DPDI online在线调度系统环境部署

DPDI online简介&#xff1a; DPDI Online 是一款基于Kettle的强大在线任务调度平台&#xff0c;凭借其高效与灵活性&#xff0c;专为调度和监控Kettle客户端生成的ETL任务而设计 DPDI online部署 DPDI服务部署文档包含依赖环境部署和应用本身部署 依赖环境部署 &#xff1…

Unity导入Avpro插件(3.0.8版本)打包安卓时报错

报错信息&#xff08;部分&#xff09; Exception while marshalling C:\Program Files\Unity\Hub\Editor\2022.3.34f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\SDK\build-tools\32.0.0\package.xml. Probably the SDK is read-only Exception while marshalling C:\Prog…

等保测评:如何应对网络攻击——构建全面的防御体系

在数字化转型的浪潮中&#xff0c;网络攻击已成为企业和组织面临的严峻挑战。等保测评&#xff0c;作为我国信息安全等级保护制度的重要组成部分&#xff0c;为企业提供了应对网络攻击的指导框架。本文旨在探讨等保测评在防御网络攻击中的关键作用&#xff0c;为企业提供实践指…

时间序列生成模型TimeGAN介绍与实现

目录 1. 模型介绍2. 问题提出3. 模型具体实现3.1 嵌入和恢复函数3.2 序列生成器和判别器3.3 联合学习编码、生成和迭代 4. 代码实现参考文献 时间序列数据在金融、医疗和物联网等领域具有广泛的应用。生成真实感的时间序列数据对于数据增强、隐私保护和模拟研究具有重要意义。T…

【Android Studio】原生应用部署第三方插件(探针)

一、本地引入包流程 &#xff08;一&#xff09;本地引入包内容 &#xff08;二&#xff09;本地引入包操作步骤 将 【probe-android-sdk】目录里面所有的aar包复制到嵌码项目工程&#xff08;App级别&#xff09;的 libs 目录下 二、添加插件 &#xff08;一&#xff09;…

代码规范 —— 数据库规范

优质博文&#xff1a;IT-BLOG-CN 一、建表规范 【1】表达是与否概率的字段&#xff0c;必须使用is_xxx的方式命令&#xff0c;数据类型是tinyint&#xff08;1表示是&#xff0c;0表示否&#xff09; 正例&#xff1a;表达逻辑删除的字段名is_active&#xff0c;0表示删除&a…

Missing or invalid credentials.(Git push报错解决方案)

参考博客&#xff1a;1 2 git push后报错Missing or invalid credentials的解决方案 1.右侧选择配置编辑器 2.搜索git.terminalAuthentication 把勾勾取消掉。 3.重启vscode。

3D数字人能一键生成?

最近有好多人询问数字人的情况&#xff0c;昨天遇到一个客户&#xff0c;我把数字人作品发给他看&#xff0c;他说“不像”&#xff0c;我把国际上别人做得最好的数字人发给他看&#xff0c;他还是说“不像”&#xff0c;我就知道这个客户没得谈了。后来我把网易公司做的数字人…

文件上传漏洞 思路方法总结

目录 为什么存在文件上传漏洞 一句话木马 文件上传攻击方式 前段验证 文件Content——Type绕过攻击 .htaccess文件绕过 文件后缀绕过攻击 文件截断绕过 竞争条件攻击 其余绕过方式 1 换行绕过&#xff1a;上传文件&#xff0c;在文件名后缀处添加换行 2 等号绕过&a…

气膜大棚:高价值花卉种植的理想选择—轻空间

在现代农业技术不断进步的今天&#xff0c;气膜大棚作为一种创新型的农业设施&#xff0c;逐渐被广泛应用于高价值花卉的种植。气膜大棚凭借其卓越的性能和环保特性&#xff0c;成为了花卉种植者们的理想选择。 气膜大棚通常采用PVDF膜材料&#xff08;聚偏二氟乙烯&#xff09…

书生大模型实战营-入门关卡-Python 基础知识

任务&#xff1a; https://github.com/InternLM/Tutorial/blob/camp3/docs/L0/Python/task.md 完成&#xff1a; 任务1&#xff1a;Python实现wordcount import re from collections import defaultdictdef wordcount(text):# 转换为小写并使用正则表达式分割单词words re.…

单细胞测序全基因组扩增(WGA)方法

1. 全基因组扩增&#xff08;whole-genome amplification&#xff0c; WGA&#xff09; 单细胞扩增能将pg级或fg级的单细胞DNA扩增为可满足测序要求的ug级DNA量&#xff0c;从而使单细胞测序变为可能。目前存在的主要三种扩增方法有&#xff1a;简并寡核苷酸引物PCR扩增&#…

一起学习LeetCode热题100道(32/100)

32.随机链表的复制(学习) 给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成&#xff0c;其中每个新节点的值都设为其对应…