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

在这里插入图片描述

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.rhkb.cn/news/394269.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于MSER和HOG特征提取的SVM交通标志检测和识别算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 MSER 4.2 HOG特征提取 4.3 SVM 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 2.算法运行软件版本 matlab2017b 3.部分核心程序 &#xff08;完整版代码包含中…

CMU15445 (Fall 2023) Project 1 - Buffer Pool 思路分享

文章目录 写在前面Task 1 - LRU-K Replacement PolicyTask 2 - Disk SchedulerTask 3 - Buffer Pool ManagerNewPageFetchPageUnpinPageDeletePageFlushPage 写在最后 写在前面 操作系统为应用程序提供了默认的缓存机制&#xff0c;DBMS作为应用程序&#xff0c;为什么不使用默…

LSLM论文

解决的问题 现在的语音模型&#xff08;SLM&#xff09;增强了语音对话的能力&#xff0c;但都局限于回合制对话&#xff0c;在实时对话的情境下与用户交互的能力有所欠缺&#xff0c;例如&#xff1a;当生成的对话不满意时被打断。所以&#xff0c;这篇论文在实时的的语音语言…

ShardingSphere自定义分布式主键生成策略、自定义分片规则

文章目录 主键生成策略源码KeyGenerateAlgorithm源码入口实现扩展 自定义分布式主键生成策略 分片算法ShardingAlgorithm实现扩展 自定义分片算法踩的坑 主键生成策略源码 开发者手册 KeyGenerateAlgorithm 全限定类名org.apache.shardingsphere.sharding.spi.KeyGenerateAl…

QT界面设计开发(Visual Studio 2019)—学习记录一

一、控件升级 简要介绍&#xff1a; 简单来说&#xff0c;控件提升就是将一个基础控件&#xff08;Base Widget&#xff09;转换为一个更特定、更复杂的自定义控件&#xff08;Custom Widget&#xff09;。这样做的目的是为了在设计界面时能够使用更多高级功能&#xff0c;而不…

环境搭建:全面详尽的 MongoDB Shell MongoDB Server介绍、安装、验证与配置指南(以 Windows 系统为主)

环境搭建&#xff1a;全面详尽的 MongoDB Shell & MongoDB Server介绍、安装、验证与配置指南&#xff08;以 Windows 系统为主&#xff09; MongoDB 是一个基于文档的 NoSQL 数据库&#xff0c;以其高性能、灵活性和可扩展性而受到广泛欢迎。本文将带您完成 MongoDB 的安装…

bpmn简单使用(制作流程图)

1、先下载依赖&#xff0c;下面是我下载的版本 "bpmn-io/properties-panel": "^3.23.0", "bpmn-js": "^17.9.1", "bpmn-js-properties-panel": "^5.6.1", "camunda-bpmn-moddle": "^7.0.1",…

CTFHUB-web-RCE-eval执行

开启题目 查看源码发现直接用蚁剑连接就可以&#xff0c;连接之后发现成功了

计算机网络408考研 2020

2020 湖科大教书匠的个人空间-湖科大教书匠个人主页-哔哩哔哩视频 计算机网络408考研 历年真题解析&#xff08;有字幕无背景音乐版&#xff09;_哔哩哔哩_bilibili 计算机网络408考研2020年真题解析_哔哩哔哩_bilibili 1 2 3 41 11 1

乡村振兴农村煤改气建设规划设计方案

1. 方案目标与背景 《乡村振兴农村煤改气建设规划设计方案》旨在响应国家乡村振兴战略&#xff0c;通过建设规划推动农村能源结构转型&#xff0c;减少燃煤造成的环境污染&#xff0c;促进农村可持续发展。 2. 农村能源消耗现状 根据2006至2007年的全国性调研&#xff0c;农…

从一个服务预热不生效问题谈微服务无损上线

作者&#xff1a;凡问、启淮 前言 本文基于阿里云技术服务团队和产研团队&#xff0c;在解决易易互联使用 MSE&#xff08;微服务引擎&#xff09;产品无损上线功能所遇到问题的过程总结而成。本文将从问题和解决方法谈起&#xff0c;再介绍相关原理&#xff0c;后进一步拓展…

4.11.seq2seq 序列到序列学习

序列到序列学习(seq2seq) ​ 使用两个循环神经网络的编码器和解码器&#xff0c;应用于序列到薛烈类的学习任务。 ​ ​ 在图中&#xff0c;特定的"<eos>"表示序列结束词元。一旦输出序列生成此词元&#xff0c;模型就会停止预测。在循环神经网络解码器的初…

JS+CSS案例:可适应上下布局和左右布局的菜单(含二级菜单)

今天,我给大家分享一个原创的CSS菜单,整个菜单全由CSS写成,仅在切换布局时使用JS。合不合意,先看看效果图。 本例图片 接下来,我来详细给大家分享它的制作方法。 文件夹结构 因为涉及到了样式表切换,所以,你需要借鉴一下我的文件夹结构。 CSS文件夹: reset.css 用于…

维吉尼亚密码加解密实现(python)

维吉尼亚密码 原理 维吉尼亚密码&#xff08;Vigenere&#xff09;是使用一系列凯撒密码组成密码字母表的加密算法&#xff0c;属于多表密码的一种简单形式。 下面给出一个例子 明文&#xff1a;come greatwall 密钥&#xff1a;crypto首先&#xff0c;对密钥进行填充使其长…

【算法】普里姆算法解决修路问题

应用场景——修路问题 1.某地有 7 个村庄&#xff08;A&#xff0c;B&#xff0c;C&#xff0c;D&#xff0c;E&#xff0c;F&#xff0c;G&#xff09;&#xff0c;现在需要修路把 7 个村庄连通 2.各个村庄的距离用边线表示&#xff08;权&#xff09;&#xff0c;比如 A - …

ORM工具之SQLAlchemy

SQLAlchemy是Python编程语言下的一款开源软件。提供了SQL工具包及对象关系映射&#xff08;ORM&#xff09;工具&#xff0c;使用MIT许可证发行。 SQLAlchemy“采用简单的Python语言&#xff0c;为高效和高性能的数据库访问设计&#xff0c;实现了完整的企业级持久模型”。SQL…

从 Pandas 到 Polars 四十四:Polars 和 数据可视化库Seaborn

在我对Matplotlib感到沮丧并发表帖子时&#xff0c;我的朋友让我试试Seaborn库。近年来我一直在使用Altair&#xff0c;因此并没有过多考虑Seaborn。然而&#xff0c;Seaborn的新界面给我留下了深刻印象&#xff0c;并且我很高兴地发现&#xff0c;Seaborn将直接接受Polars的Da…

【web安全】权限漏洞之未授权访问

一.Jenkins未授权访问漏洞 步骤一&#xff1a;使用以下fofa语法进行搜索 port"8080" && app"JENKINS" && title"Dashboard [Jenkins]" 步骤二&#xff1a;进入执行页面http://xxx.xxx.xxx.xxx:xxxx/manage/script/index.php 执…

Linux下自动监控进程运行状态

目录 背景应用举例1、使用crontab脚本监控服务2、使用shell脚本监控服务2.1 编写自定义监控脚本2.2 运行脚本 背景 假设有一个服务需要长期运行&#xff0c;但可能会由于某种原因导致服务意外停止&#xff0c;不能及时发现&#xff0c;某天来到公司后发现出问题了才意识到服务…

(Qt) QThread 信号槽所在线程

文章目录 &#x1f481;&#x1f3fb;前言&#x1f481;&#x1f3fb;Code&#x1f481;&#x1f3fb;‍♂️Code&#x1f481;&#x1f3fb;‍♂️环境 &#x1f481;&#x1f3fb;当前线程信号&#x1f481;&#x1f3fb;‍♂️默认效果&#x1f481;&#x1f3fb;‍♂️Qt::…