Cpp类和对象(上)(3)

文章目录

  • 前言
  • 一、面向过程与面向对象初步认识
  • 二、类的引入
  • 三、类的定义
  • 四、类的访问限定符及类的封装
    • 类的访问限定符
    • 类的封装
  • 五、类的作用域(类域)
  • 六、类的实例化
  • 七、类对象模型
    • 如何计算类对象的大小
    • 类对象的存储方式猜测
  • 八、this指针
    • this指针的引出
    • this指针的特性
  • 九、C语言和C++实现Stack的对比
  • 总结


前言

  哈哈,类和对象可以说是我们正式学习Cpp的第一节课
  上篇还不算很难,甚至可以说还是蛮有意思的

正文开始!


一、面向过程与面向对象初步认识

你需要很早地有个认识:

  1. C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。
  2. C++是基于面向对象的,关注的是对象,将一件事拆分成不同的对象,靠对象之间的交互完成。

举个例子,假设你点了一份外卖:
  面向过程: 你下单——商家做饭——骑手取餐——商家骑手交接——骑手送餐——你拿到饭菜
  面向对象: 骑手、商家、顾客这三个 类 实例化产生的对象之间的交互

二、类的引入

在C语言中,结构体中只能定义变量,但在C++中,结构体内不仅可以定义变量,还可以定义函数

struct Test
{//成员变量int a;double b;//成员函数int Add(int x, int y){return x + y;}
};

可是,我们在C++中更喜欢用 class 来代替,下面来看类的定义:

class className
{// 类体:由成员函数和成员变量组成}; // 一定要注意后面的分号

类体中内容称为类的成员,其中类的成员:

  1. 类中的变量称为类的属性成员变量
  2. 类中的函数称为类的方法成员函数

三、类的定义

声明和定义全部放在类体中

请注意,成员函数如果在类中定义,编译器可能会将其当成内联函数处理

在这里插入图片描述
声明放在头文件(.h)中,定义放在源文件(.cpp)中

请注意,成员函数名前需要加 “类名::”

在这里插入图片描述

  一般情况下,更期望采用第二种方式,因为这样体现了面对对象编程的封装特性提高代码的可维护性

  你再看上面这两段代码的成员变量,你可能奇怪为什么每个变量前都有个下划线_,这是为了与成员函数的形参区分开

class Date
{
// 你可能奇怪这个 public 和 private,先不急哈
public:void Init(int year){// 区分一个类的成员变量和成员函数的形参,通常将成员变量前或者后加一个“_”_year = year;// 如若成员变量不加“_”,就变成了year = year; 局部变量优先,导致错误}
private:int _year;
};

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

类的访问限定符

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

在我们还没学到继承之前,你暂时先把ptotected 和 private 等同吧

  1. public修饰的成员(成员函数或者成员变量)在类外可以直接被访问;
  2. protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的);
  3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止;
  4. 如果后面没有访问限定符,作用域就到 }, 即类结束;
  5. class的默认访问权限为private,struct为public(因为struct要兼容C);

请注意,访问限定符只在编译时期有效,当数据映射到内存后,没有任何访问限定符的区别

类的封装

封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互

绝对的自由不是自由,印度火车不加以管制,导致一辆车除了座位,旁侧扶手甚至车顶都可以载人,危险程度无可置疑地增大,而封装本质上是一种高效的管理,对访问权限的限制有时候是为了我们更好的使用,这点大家可以有个意识,慢慢再来体会

  再比如计算机,用户无需关心内部核心部件,比如主板上线路是如何布局的,CPU内部是如何设计的等,用户只需要知道,怎么开机、怎么通过键盘和鼠标与计算机进行交互即可
  因此计算机厂商在出厂时,在外部套上壳子,将内部实现细节隐藏起来,仅仅对外提供开关机、鼠标以及键盘插孔等,让用户可以与计算机进行交互即可

五、类的作用域(类域)

  类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员,需要使用“::”作用域解析符指明成员属于哪个类域

class Person
{
public:// 显示基本信息void ShowInfo();
private:char* _name;  //姓名char* _sex;   //性别int _age;     //年龄
};//这里需要指定 ShowInfo 是属于 Person 这个类域
void Person::ShowInfo()
{cout << _name << "-" << _sex << "-" << _age << endl;
}

六、类的实例化

用类创建对象的过程称为类的实例化

  类本质上也是一种数据类型(如int,float,double等)只不过类是一种比较复杂的数据类型,它包含多种可自助实现的功能(类的成员函数),既然如此,那类其实并没有实际分配空间,如果出现没有对类进行实例化操作,而私自调用类中成员变量会报错,而通过类实例化出来的对象是占用内存空间

简单来说,类就像图纸,你得用它来建设房子

在这里插入图片描述

七、类对象模型

如何计算类对象的大小

我们先来看以下代码:

#include<iostream>
using namespace std;class A1 {
public:void f1(){}
private:int _a;
};// 类中仅有成员函数
class A2 {
public:void f2() {}
};// 类中什么都没有---空类
class A3
{};int main()
{// 4 1 1cout<<sizeof(A1)<<" "<<sizeof(A2)<<" "<<sizeof(A3);return 0;
}

注意结构体内存对齐
可以看出来输出结果为 4、1、1,这可以引发我们的一些猜测:

类对象的存储方式猜测

猜测一:对象中包含类的各个成员
在这里插入图片描述
  观察到A1的输出结果为4,否决,其实我们分析以下,道理也很显然,假如每个实例化的对象的成员函数都开空间,那有一百个实例化对象就开一百份空间,而这些实例化的对象的属性固然不一样,但函数却是一样的,这造成了浪费

猜测二:只保存成员变量,成员函数存放在公共的代码段
在这里插入图片描述
在这里插入图片描述
  这就解释了为什么A1的大小为4,但是为什么A2和A3的大小不是0而是1呢?
  你分析一下,什么是定义,什么是声明,定义是确确实实要开空间的,尽管没有属性,但我们仍要标记一下,所以空类比较特殊,编译器给空类一个字节来唯一标识这个类的对象,表示这个对象存在过,可能有成员函数

八、this指针

this指针的引出

#include <iostream>
using namespace std;class Date
{
public:void Display(){cout << _year << "-" << _month << "-" << _day << endl;}void SetDate(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year; // 年int _month; // 月int _day; // 日
};int main()
{Date d1, d2;//实例化两个日期类d1.SetDate(2021, 5, 25);//设置d1的日期d2.SetDate(2021, 5, 26);//设置d2的日期d1.Display();//打印d1的日期d2.Display();//打印d2的日期return 0;
}

  我们观察,Date 类中有 Init 与 Print 两个成员函数,对于函数体没有关于不同对象的区分,当不同对象调用函数时,该函数如何知道应该设置或打印 d1对象 ,而不是 d2对象 呢

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

在这里插入图片描述
  编译器进行编译时,看到的成员函数实际上也和我们所看到的不一样,每个成员函数的第一个形参实际上是一个隐含的this指针,该指针用于接收调用函数的对象的地址,用this指针就可以很好地访问到该对象中的成员
在这里插入图片描述

this指针的特性

  1. this指针的类型:类类型* const,即成员函数中,不能给this赋值
  2. this指针只能在“成员函数”的内部使用。
  3. this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this形参,所以对象中不存储this指针。
  4. this指针是成员函数第一个隐含的指针形参,一般情况this指针存在栈里面,因为是形参。或者由编译器通过ecx寄存器自动传递,不需要用户传递。

不妨我们再通过以下代码来深入了解this指针:

#include <iostream>
using namespace std;class A
{
public:void PrintA(){cout << _a << endl;}void Show(){cout << "Show()" << endl;}
private:int _a;
};int main()
{A* p = nullptr;  //p->Show();       // 第一句代码//p->PrintA();     // 第二句代码
}

  你可能看到指针p是一个空指针,而第二句代码和第三句代码都通过操作符“->”,间接性的执行了对p的解引用操作,所以你认为程序会崩溃
  其实不然,当程序执行第一句代码时,程序不会崩溃,会正常打印出字符串"Show()",而当程序执行第二句代码时,程序才会因为内存的非法访问而崩溃

  不要陷入思维固化,指针p确实是一个类的空指针,但当执行第一句代码时,程序并不会崩溃。第一句代码并没有对空指针p进行解引用,因为Show等成员函数地址并没有存到对象里面,成员函数的地址是存在公共代码段的

  当程序执行第二句代码时,会因为内存的非法访问而崩溃。执行第二句代码时,调用了成员函数PrintA,这里并不会产生什么错误(理由同上),但是PrintA函数中打印了成员变量_a,成员变量_a只有通过对this指针进行解引用才能访问到,而this指针此时接收的是nullptr,对空指针进行解引用必然会导致程序的崩溃

九、C语言和C++实现Stack的对比

C语言实现栈
观察C语言实现,我们会发现:

  1. 每个函数的第一个参数都是Stack*
  2. 函数中必须要对第一个参数检测,因为该参数可能会为NULL
  3. 函数中都是通过Stack*参数操作栈的
  4. 调用时必须传递Stack结构体变量的地址

  结构体中只能定义存放数据的结构,操作数据的方法不能放在结构体中,即数据和操作数据的方式是分离开的,而且实现上相当复杂一点,涉及到大量指针操作,稍不注意可能就会出错。

Cpp实现栈
观察C++实现,我们会发现:
  C++中通过类可以将** 数据 以及 操作数据的方法进行完美结合**,通过访问权限可以控制那些方法在类外可以被调用,即封装,在使用时就像使用自己的成员一样,更符合人类对一件事物的认知。而且每个方法不需要传递Stack的参数了,编译器编译之后该参数会自动还原,即C++中 Stack 参数是编译器维护的,C语言中需用用户自己维护


总结

  怎么样,本节内容开始有意思了起来,接下来的中篇会更有意思!

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

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

相关文章

天池Fashion AI 比赛失败经历分享

关联比赛: FashionAI全球挑战赛—服饰关键点定位 昨天是天池Fashion AI初赛Deadline&#xff0c; 成绩出来复赛都没能进&#xff0c;虽然结果很遗憾&#xff0c;但在比赛的过程中也接触到了不少的新东西&#xff0c;希望能在这里把我尝试过的方法都分享出来。作为对自己的总结…

EPLAN中如何切换编辑区的背景颜色为黑色?

EPLAN中如何切换编辑区的背景颜色为黑色&#xff1f; 如下图所示&#xff0c;打开EPLAN软件&#xff0c;打开或新建一个项目&#xff0c; 如下图所示&#xff0c;点击选项----设置&#xff0c; 在弹出的窗口中找到用户----图形的编辑------2D&#xff0c;在右侧找到颜色设置---…

便携式气象监测站的工作原理

型号&#xff1a;TH-BQX9】便携式气象环境监测站是一种集数据采集、处理、传输于一体的便携式设备&#xff0c;主要用于实时、准确地监测环境中的多种气象要素。便携式气象环境监测站通常能够监测多种气象参数&#xff0c;包括但不限于温度、湿度、风速、风向、气压、降雨量、太…

Java虚拟机 - 实战篇

一、内存调优 1. 什么是内存泄漏 &#xff08;1&#xff09;内存溢出和内存泄漏 2. 监控Java内存的常用工具 &#xff08;1&#xff09;Top命令 &#xff08;2&#xff09;VisualVM &#xff08;3&#xff09;Arthas &#xff08;4&#xff09;Prometheus Grafana &#xff…

【C++STL简介】——我与C++的不解之缘(八)

前言 学过了C的模版&#xff0c;接下来学习C中的STL&#xff08;标准模版库&#xff09;&#xff0c;先来了解一下STL是啥 一、什么是STL STL&#xff08;standard template libaray 标准模版库&#xff09;&#xff1a;是C标准库的重要组成部分&#xff0c;不仅是一个可复用的…

cmake的下载与安装

介绍&#xff1a; CMake是一个跨平台的安装&#xff08;编译&#xff09;工具&#xff0c;可以用简单的语句来描述所有平台的安装(编译过程)。 能够输出各种各样的makefile或者project文件&#xff0c;能测试编译器所支持的C特性,类似UNIX下的automake。 CMake 的组态档取名为…

[Java]SpringBoot能力进阶

配置优先级 SpringBoot中支持三种格式的配置文件 优先级: application.properties文件 > application.yml文件 > application.yaml文件 SpringBoot除了通过配置文件配置属性, 还支持Java系统属性和命令行参数的方式 进行属性配置 1.在IDEA中配置java系统属性和命令行参…

网络安全-shire写任务计划、反弹shell、写私钥

目录 一、环境 二、 介绍 三、开始做题 四、写公钥 一、环境 网上自己找 二、 介绍 我们经过前面文章很清楚知道&#xff0c;shiro是将数据存储在内存当中&#xff0c;内存落盘实现一个数据存储&#xff0c;而当其结合python&#xff0c;python将登录的session存储到shiro里…

python绘制月亮

import matplotlib import matplotlib.pyplot as plt import moviepy.editor as mpymatplotlib.rcParams[font.family] SimHei# 坐标列表 positions [(0, 0), (1 / 4, 1 / 4), (1 / 3, 1 / 4), (1 / 2, 1 / 4), (2 / 3, 1 / 4),(3 / 4, 1 / 4), (1, 1 / 4), (5 / 4, 1 / 4), …

桌面上的文件突然不见了怎么找回?快速恢复技巧分享

在日常使用电脑的过程中&#xff0c;我们习惯于将经常使用的文件或者快捷方式放置在桌面上&#xff0c;以便于快速访问。然而&#xff0c;有时我们会发现桌面上的某些文件突然不见了&#xff0c;这可能会让人感到惊慌和困惑。面对这种情况&#xff0c;我们应该如何找回这些突然…

路由器全局配置DHCP实验简述

一、路由器配置 reset saved-configuration Warning: The action will delete the saved configuration in the device. The configuration will be erased to reconfigure. Continue? [Y/N]:y Warning: Now clearing the configuration in the device. Info: Succeeded in c…

02 基于STM32的按键控制继电器驱动电机

本专栏所有源资料都免费获取&#xff0c;没有任何隐形消费。 注意事项&#xff1a;STM32仿真会存在各种各样BUG&#xff0c;且尽量按照同样仿真版本使用。本专栏所有的仿真都采用PROTEUS8.15。 本文已经配置好STM32F103C8T6系列&#xff0c;在PROTUES仿真里&#xff0c;32单片…

教程 | ArcGIS Pro如何自动保存数据编辑内容

目录 1、工程自动保存 2、数据编辑自动保存 世界上最痛苦的事情就是&#xff1a; 软件崩溃&#xff0c;我没保存&#xff01;&#xff01;&#xff01; 电脑死机&#xff0c;我没保存&#xff01;&#xff01;&#xff01; 突然断电&#xff0c;我没保存&#xff01;&…

开源项目的悲哀

开源下载器 Aria 的开发者因为其项目被诈骗人员使用&#xff0c;导致开发者遭受跨省追捕&#xff0c;作者于 2024 年 8 月 16 日在 GitHub 上宣布删除了项目的全部源码。 Aria 是一个高性能、轻量级、易于使用的文件下载框架&#xff0c;主要应用于Android 平台&#xff0c;拥有…

10个A/B测试指标以分析结果和衡量成功

为什么A/B测试分析很重要&#xff1f; 到现在&#xff0c;您可能已经熟悉了A/B测试的基本概念及其用途。 简而言之&#xff0c;A/B测试是将两个或多个着陆页、营销资产或单个元素&#xff08;如标题&#xff09;进行对比&#xff0c;以帮助您找出哪个表现最好。 这些测试帮助…

Varjo在芬兰开设新工厂,以满足国防部门在XR模拟训练中的需求

在军事国防领域&#xff0c;全新技术的投入使用最看重的就是保密与安全。作为全球领先的XR头戴式显示器提供商Varjo&#xff0c;近日正式宣布将在位于芬兰的赫尔辛基开设一家新的安全制造工厂。 此次工厂扩建将使Varjo能够满足国防训练和模拟领域对其高分辨率XR解决方案日益增…

Qwen2-VL环境搭建推理测试

引子 2024年8月30号&#xff0c;阿里推出Qwen2-VL&#xff0c;开源了2B/7B模型&#xff0c;处理任意分辨率图像无需分割成块。之前写了一篇Qwen-VL的博客&#xff0c;感兴趣的童鞋请移步&#xff08;Qwen-VL环境搭建&推理测试-CSDN博客&#xff09;&#xff0c;这么小的模…

揭秘!当业务方需求模糊,产品经理如何施展‘化雾为金’的神奇策略!

引言 在产品管理的实践中&#xff0c;产品经理经常会遇到业务方无法清晰表达需求的情况。这可能是由于业务方对问题的理解不够深入&#xff0c;或者缺乏将业务需求转化为产品需求的经验。作为资深产品经理&#xff0c;我们需要采取一系列策略来应对这一挑战&#xff0c;确保产…

​‌Macbook如何玩《黑神话:悟空》‌2024最新详细方法

‌Mac用户可以通过几种方法玩《黑神话&#xff1a;悟空》‌。 ‌使用虚拟机‌&#xff1a;通过Parallels Desktop等虚拟机软件&#xff0c;在Mac上运行Windows系统&#xff0c;并在其中安装和运行《黑神话悟空》。这种方法需要Mac电脑满足游戏的基础配置要求。 不过如果电脑有虚…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《基于模型-数据混合驱动的区域能源互联网韧性在线评估》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…