类与对象(一)

目录

1 什么是面向过程和面向对象

1.1举例

2类的引入

3类的定义

3.1类的两种定义方式:

4.类的访问限定符及封装

4.1访问限定符

4.1.1为什么要有访问限定符

4.1.2有哪些访问限定符呢?

 4.1.3简单举例理解

4.1.4C++中的class与struct的区别(面试问题)

 4.2封装

4.2.1什么是封装?(重要)

 5.类的作用域

 6.类的实例化

7. 类对象模型

7.1如何计算类对象的大小

7.2为什么空类的大小为1?

7.3函数在类里面的存储形式? 

7.4面试题

8.this指针

8.1this指针的引出

 8.2this指针的特性

8.3关于this指针的面试题

1. this指针存在哪里?

2. this指针可以为空吗? 

8.4思考:


1 什么是面向过程和面向对象

我们知道,c语言是一门面向过程的语言,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。而c++、Java则是一个面向对象的语言,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完 成。面向过程"和"面向对象"是两种不同的编程范式,它们反映了程序设计和组织代码的不同思想

面向过程

思想:面向过程编程的核心思想是将问题划分为一系列的步骤,每个步骤都是一个函数或者是一个子过程。程序的执行按照一些特定的步骤依次进行。

面向对象

思想:面向对象编程的核心是将程序看作是对象的集合,而不是一系列步骤的集合。对象是对数据和行为的封装,具有特定的属性和方法。

1.1举例

当我们将程序描述成洗衣服这一个事情。

对于面向过程的思想来说,我们将洗衣服的每一个子过程都列举出来:准备好要洗的衣服-->准备一个盆-->放水-->放衣服-->放洗服......

 对于面向对象的思想来说,我们先把整个事情划分成几个对象:人、衣服、洗衣机、洗衣粉

整个事情的过程:人将衣服丢进洗衣机、倒入洗衣粉、启动洗衣机

整个过程是由这些对象交互完成的,人不需要关心洗衣机是如何工作的

总结:不同的思想看待问题的角度不同,实现的方式也会有差别。选择面向过程还是面向对象通常取决于问题的性质和开发者的偏好。大多数现代编程语言支持两种范式,而实际的项目中通常会根据问题的需求灵活选择使用这两种范式。 

2类的引入

C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。比如: 之前在数据结构初阶中,用C语言方式实现的栈,结构体中只能定义变量;现在用C++方式实现, 会发现struct中也可以定义函数。

 

上面结构体的定义,在C++中更喜欢用class来代替。

3类的定义

类的定义和结构体很相似

class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。 类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者 成员函数

3.1类的两种定义方式:

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

2、类声明和成员函数定义分开。类声明放在.h的头文件中,类体里面也只有成员函数的声明,将成员函数定义在.cpp源文件中。为了防止命名冲突,这样定义的成员函数需要在前面加类的名称(类似命名空间声明)。

为了代码的维护性,一般用第二种类定义方式。

4.类的访问限定符及封装

4.1访问限定符

4.1.1为什么要有访问限定符

对于一个类来说,也许会有很多的成员函数和成员属性,有些变量我们希望它能被外部直接访问,当然,大多数的变量我们都不希望外不能够直接访问,这样就太不安全了。所以我们需要使用访问限定符来划定属性和方法的访问权限,也便于我们对类的管理。

4.1.2有哪些访问限定符呢?

public(公有):使用 public 关键字标识,表示成员对外公开,可以在任何地方访问。这意味着类的外部代码可以直接访问公有成员

protected(保护):使用 protected 关键字标识,表示成员对于类的子类是可见的,但对于类的外部代码是私有的。

private(私有):使用 private 关键字标识,表示成员仅在类的内部可见,外部代码无法直接访问。私有成员只能在类的内部使用

说明:

访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止

如果后面没有访问限定符,作用域就到 } 即类结束。

class的默认访问权限为private,struct为public(因为struct要兼容C)。

访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别、

也就是说,访问限定符只是能否访问的一道门,通过这扇门后就不会管你了。

 4.1.3简单举例理解

定义以下类

外部访问public下的成员属性及方法,正常编译

外部访问private下的成员属性及方法,报错

4.1.4C++中的class与struct的区别(面试问题)

classstruct 之间的差异主要体现在默认的成员访问权限和继承方式上。除了这些,它们在语法上几乎是一样的

1、默认的成员访问权限:

  • class 中,默认的成员访问权限是 private
  • struct 中,默认的成员访问权限是 public

2、继承方式:

  • 通过 class 定义的派生类,默认的继承权限是 private
  • 通过 struct 定义的派生类,默认的继承权限是 public

对比两者我们可以发现,其实class和struct大致没有什么区别,class能做到的struct也能做到,只不过两者的默认权限有些差异,取决于具体的需求和编码风格。

 4.2封装

4.2.1什么是封装?(重要)

将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来 和对象进行交互。在实现封装时,通常使用访问修饰符来设置成员的访问权限。例如,使用 private 成员来隐藏内部细节,而通过 public 成员提供对外的接口

 举例

假设实现一个电脑类,开机键实现开机操作,对于用户来说无需在意开机的具体细节,只需要知道按下去就能开机开机键就是我们对外的接口。这样一来,用户能够更加方便的使用类,同样,避免了用户直接使用内部属性,提高了安全性

 5.类的作用域

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

 6.类的实例化

在面向对象编程中,类是一种模板或蓝图,对象是根据这个模板创建出来的具体实体。实例化是通过调用类的构造函数来创建对象的过程。用类类型创建对象的过程,称为类的实例化.

1. 类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没 有分配实际的内存空间来存储它

2. 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量

int main()
{
 Person._age = 100;   // 编译失败:error C2059: 语法错误:“.”
 return 0;
}

Person类是没有空间的,只有Person类实例化出的对象才有具体的年龄

7. 类对象模型

7.1如何计算类对象的大小

相对于c语言的结构体,c++的结构体可以在里面直接定义函数,这样一来有了函数的结构体的大小又怎么算呢?类的大小又怎么算呢?

对c语言的结构体大小计算还不清楚的可以去看看我之前的博客,专门介绍了结构体内存对齐原则

c语言结构体的内存对齐-CSDN博客

观察以下代码

7.2为什么空类的大小为1?

 分析A3,A3是一个空类,为什么sizeof A3等于1呢?

在C++中,一个空类(没有任何成员变量或成员函数)的大小通常为1字节。这是因为在C++中,空类的实例需要有独一无二的地址,以便在使用指针操作时能够区分不同的对象

7.3函数在类里面的存储形式? 

分析A2,A2类体只有一个函数,为什么sizeof A2等于1呢?

首先我们先思考这样一个事实。对于一个类来说,其每个实例化对象里的成员变量的值可能都不一样。但是其中的成员方法都是一样的。如果每实例化一个对象都开辟空间存放其成员函数,这样一来就会浪费很多空间。于是,c++将类中的成员函数都存储在程序的代码段(text segment)中,而不是存储在对象的实例中这样可以节省内存空间这意味着所有对象共享相同的成员函数代码

简单理解就是,有一个公共区域存储该类的成员函数,每当有对象要调用其成员函数时,就去这个区域里面去调用。

这也就是为什么我们siziof A2等于1了

7.4面试题

1、结构体怎么对齐?为什么要进行内存对齐?

2、如何让结构体按照指定的对齐参数进行对齐?能否按照3、4、5即任意字节对齐? 

3、什么是大小端?如何测试某台机器是大端还是小端,有没有遇到过要考虑大小端的场景

之前的博客里有讲解

c语言结构体的内存对齐-CSDN博客

c语言内功修炼--深度剖析数据的存储-CSDN博客

8.this指针

8.1this指针的引出

观察以下代码

#include<iostream>
using namespace std;

//日期类
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(2024, 3, 2);
	d1.Print();

	d2.Init(2024, 3, 1);
	d2.Print();

	return 0;
}

上述代码定义了一个日期类,类里面有Init和Print两个成员函数,函数体中没有对象的区分,当实例化对象d1调用Init函数时,该成员函数怎么区分是哪个对象来调用它的呢?因为之前我们已经讲过,类里面的成员函数都是放在外面的公共区域,代码只有一份,也就是说,如果不能区分是哪个对象来调用成员函数,那就会发生错误,毕竟每个对象的成员变量都是不一样的。

于是,c++通过引入一个this指针来解决类似问题。

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

也就是说,在你定义一个成员函数的时候,这个函数的参数里面就有一个你隐式的this指针,在你实例化某个对象并调用这个成员函数的时候,这个this指针会指向该对象的地址,告诉这个函数是哪个对象在调用它。

 8.2this指针的特性

1. this指针的类型:类类型* const,即成员函数中,不能给this指针赋值

2. 只能在“成员函数”的内部使用

3. this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给 this形参。所以对象中不存储this指针。

4. this指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递

8.3关于this指针的面试题

1. this指针存在哪里?

编译器在生成程序时加入了获取对象首地址的相关代码。并把获取的首地址存放在了寄存器ECX中(VC++编译器是放在ECX中,其它编译器有可能不同)。也就是成员函数的其它参数正常都是存放在栈中。而this指针参数则是存放在寄存器中。类的静态成员函数因为没有this指针这个参数,所以类的静态成员函数也就无法调用类的非静态成员变量。

2. this指针可以为空吗? 

this指针是否可以为空需要看情况,如果被调用的成员函数本身与成员属性无关,也就意味着不需要解引用this指针,不解引用this指针的话,也就随便它是个啥了。

举例:

有的朋友可能会问,t不是nullptr吗?为什么解引用还不会报错?有->符号并不意味着就解引用了,要看是否真的访问了所指空间。而上面我们已经讲过,print函数并不在类里面,也就意味着t->print()并没有在t的地址上去访问,所以即使t为空也能访问到里面的成员函数。只不过这个时候需要注意判断this指针是否可以为空

8.4思考:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Tomcat基础及与Nginx实现动静分离,搭建高效稳定的个人博客系统

目录 引言 一、TOMCAT基础功能 &#xff08;一&#xff09;自动解压war包 &#xff08;二&#xff09;状态页 1.登录状态页 2.远程登录 &#xff08;三&#xff09;服务管理界面 &#xff08;四&#xff09;Host虚拟主机 1.设置虚拟主机 2.建立站点目录与文件 二、实…

python 使用curl_cffi 绕过jax3指纹-Cloudflare 5s盾

现在越来越多的网站已经能够通过JA3或者其他指纹信息&#xff0c;来识别你是不是爬虫了。传统的方式比如换UA&#xff0c;加代理是没有任何意义了&#xff0c;所以这个时候我们就需要使用到curl_cffi 了。 1.TLS 指纹是啥&#xff1f; 在绝大多数的网站都已经使用了 HTTPS&am…

Java项目:32 基于springboot的课程作业管理系统(含源码数据库+文档免费送)

作者主页&#xff1a;舒克日记 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 管理员&#xff1a;首页、个人中心、公告信息管理、班级管理、学生管理、教师管理、课程类型管理、课程信息管理、学生选课管理、作业布置管理、作业提…

sprintboot集成flink快速入门demo

一、flink介绍 Flink是一个批处理和流处理结合的统一计算框架&#xff0c;其核心是一个提供了数据分发以及并行化计算的流数据处理引擎。它的最大亮点是流处理&#xff0c;是业界最顶级的开源流处理引擎。Flink最适合的应用场景是低时延的数据处理&#xff08;Data Processing&…

⭐每天一道leetcode:13.罗马数字转整数(简单)

⭐今日份题目 罗马数字包含以下七种字符: I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 100…

MATLAB知识点:条件判断switch-case-otherwise-end语句

​讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili 节选自​第4章&#xff1a;MATLAB程序流程控制 switch翻译成…

使用C语言 打印出所有的水仙花数

水仙花数 一.什么是水仙花数二.如何获取一个数的每一位数三.如何计算一个数有几位数四.计算出所有的水仙花数 一.什么是水仙花数 水仙花数的定义&#xff1a;“水仙花数”是指一个n位数&#xff0c;其各位数字的n次方之和确好等于该数本身&#xff0c;如:153&#xff1d;1^ 3&a…

寻找峰值[中等]

优质博文IT-BLOG-CN 一、题目 峰值元素是指其值严格大于左右相邻值的元素。给你一个整数数组nums&#xff0c;找到峰值元素并返回其索引。数组可能包含多个峰值&#xff0c;在这种情况下&#xff0c;返回 任何一个峰值 所在位置即可。 你可以假设nums[-1] nums[n] -∞。 你…

【Python】批量读取文件夹中的excel文件

示例展示 代码 import os import pandas as pd folder_path r"C:\Users\admin\Desktop\excelfile" extension"xlsx" files [file for file in os.listdir(folder_path) if file.endswith(. extension)] for file in files:filepath os.path.join(folde…

ChatGPT支持下的PyTorch机器学习与深度学习技术应用

近年来&#xff0c;随着AlphaGo、无人驾驶汽车、医学影像智慧辅助诊疗、ImageNet竞赛等热点事件的发生&#xff0c;人工智能迎来了新一轮的发展浪潮。尤其是深度学习技术&#xff0c;在许多行业都取得了颠覆性的成果。另外&#xff0c;近年来&#xff0c;Pytorch深度学习框架受…

运用qsort函数进行快排并使用C语言模拟qsort

qsort 函数的使用 首先qsort函数是使用快速排序算法来进行排序的&#xff0c;下面我们打开官网来查看qsort是如何使用的。 这里有四个参数&#xff0c;首先base 是至待排序的数组的首元素的地址&#xff0c;num 是值这个数组的元素个数&#xff0c;size 是指每个元素的大小&am…

数字化转型导师坚鹏:证券公司数字化转型战略、方法与案例

证券公司数字化转型战略、方法与案例 课程背景&#xff1a; 数字化转型背景下&#xff0c;很多机构存在以下问题&#xff1a; 不清楚证券公司数字化转型的发展战略&#xff1f; 不知道证券公司数字化转型的核心方法&#xff1f; 不知道证券公司数字化转型的成功案例&am…

第四十八回 解珍解宝双越狱 孙立孙新大劫牢-Python模块和包概念与使用

吴用对宋江说&#xff0c;有个人&#xff0c;他是石勇的关系&#xff0c;与祝家庄的峦廷玉关系好&#xff0c;还是杨林、邓飞的老相识&#xff0c;他有一计.... 原来在宋江攻打祝家庄的时间段&#xff0c;山东海边登州也发生了一件事。登州山下有一家猎户&#xff0c;弟兄两个…

Linux下进程相关概念详解

目录 一、操作系统 概念 设计操作系统的目的 定位 如何理解“管理” 系统调用和库函数概念 二、进程 概念 描述进程—PCB&#xff08;process control block&#xff09; 查看进程 进程状态 进程优先级 三、其它的进程概念 一、操作系统 概念 任何计算机系统都包…

HPE ProLiant MicroServer Gen8更换坏硬盘(RAID 1+0)

HPE ProLiant MicroServer Gen8今天硬盘告警&#xff0c;坏了一块硬盘&#xff08;估计还是由于上次突然断电导致的&#xff09;&#xff0c;关机&#xff0c;拆下坏硬盘&#xff0c;更换新硬盘&#xff0c;开机后按了一次F1键&#xff0c;系统继续启动并正常使用&#xff0c;同…

VueCli的安装与卸载

文章目录 一.Node安装包的报读网盘提取码二、Vue脚手架Cli三、Vue-CLI使用步骤(自定义安装)1.转换路径并创建项目2.创建步骤的解释(保姆级)3.等待vue项目自己创建好(保姆级) 四、通过npm对vue的安装与卸载 一.Node安装包的报读网盘提取码 下面的链接为地址: Node的百度网盘提取…

面试准备:排序算法大汇总 C++

排序算法总结 直接插入排序 取出未排序部分的第一个元素&#xff0c;与已排序的部分从后往前比较&#xff0c;找到合适的位置。将大于它的已排序的元素向后移动&#xff0c;将该元素插入到合适的位置。 //1. 直接插入排序 void InsertionSort(vector<int>& nums){f…

#WEB前端(HTML属性)

1.实验&#xff1a;a,img 2.IDE&#xff1a;VSCODE 3.记录&#xff1a; a: href插入超链接 默认情况下在本窗口打开链接, target可以设置打开的窗口,parent在父窗口打开&#xff0c;blank新开串口打开,top在顶层串口打开,self为默认在本窗口打开 img: 插入图片 可以插…

走进SQL审计视图——《OceanBase诊断系列》之二

1. 前言 在SQL性能诊断上&#xff0c;OceanBase有一个非常实用的功能 —— SQL审计视图(gv$sql_audit)。在OceanBase 4.0.0及更高版本中&#xff0c;该功能是 gv$ob_sql_audit。它可以使开发和运维人员更方便地排查在OceanBase上运行过的任意一条SQL&#xff0c;无论这些SQL是成…

基于 Amazon EKS 的 Stable Diffusion ComfyUI 部署方案

01 背景介绍 Stable Diffusion 作为当下最流行的开源 AI 图像生成模型在游戏行业有着广泛的应用实践&#xff0c;无论是 ToC 面向玩家的游戏社区场景&#xff0c;还是 ToB 面向游戏工作室的美术制作场景&#xff0c;都可以发挥很大的价值&#xff0c;如何更好地使用 Stable Dif…