【C++基础(五)】类和对象(上)

news2024/11/27 9:42:58

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:C++初阶之路⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你学习C++
  🔝🔝


在这里插入图片描述

类和对象-上

  • 1. 前言
  • 2. 类的引入
  • 3. 类的定义
  • 4. 类的访问限定符
  • 5. 类的实例化
  • 6. 类对象模型
    • 6.1 类对象的存储模式
  • 7. this指针
    • 7.1 this指针的特性
    • 7.2 this指针的用处
  • 8. 总结以及拓展

1. 前言

C语言是面向过程的语言
关注的是过程
而C++是面向对象的语言
关注的是对象

而类和对象就是面向对象的基础!

在这里插入图片描述

C++为了兼容C语言
保留了原先的玩法,并且增加了新的玩法

本章重点:

本篇文章着重讲解类的概念,基本特性
成员函数的性质,和最重要的this指针


2. 类的引入

C语言的结构体功能单一
只能定义成员变量,不能定义函数
而C++中新增了一个玩法:
可以定义成员函数

比如:

struct NEO
{
	int a;
	char b[20];
	void test()//成员函数
	{
		cout<<"杭州电子科技大学"<< endl;
	}
	void push(char ch,int i)//成员函数
	{
		b[i] = ch;
	}
};

int main()
{
	NEO tmp;
	tmp.test();//会打印"杭州电子科技大学"
	tmp.push('a',1);//数组b下标为1的位置会被插入一个字符'a'
}

在C++中,C的结构体就是类
并且C++中更喜欢用class替代struct


3. 类的定义

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

类的定义与结构体类似
只不过将struct换成了class

类成员函数的两种定义方式:

  1. 声明和定义都放在类中:
class people
{
	char* name;
	char* sex;
	int height;
	int age;
	void peoinfo()//打印此人的消息
	{
		cout<<name<<" "<<sex<<" "<<height<<" "<<age;
	}
};

这个类的成员函数的声明和定义都在类中
编译器就可能把此函数当作内联处理!
只要是在类中定义的函数都会被看作内联

当然这只是给编译器一建议
具体会不会内当作内联要看代码长度

  1. 类函数声明定义分开

一般说的声明和定义分开是指:
声明放在.h文件,定义放在.cpp文件

.h文件

class people
{
	char* name;
	char* sex;
	int height;
	int age;
	void peoinfo()//打印此人的消息
};

.cpp文件(错误实例)

void peoinfo()//打印此人的消息
	{
		cout<<name<<" "<<sex<<" "<<height<<" "<<age;
	}

注意:在另一个文件中,必须要加上类名::
否则系统不知道你是要新定义一个函数
还是要定义已经声明过的函数

正解:

void people::peoinfo()//打印此人的消息
	{
		cout<<name<<" "<<sex<<" "<<height<<" "<<age;
	}

4. 类的访问限定符

首先介绍三个访问限定符:

在这里插入图片描述

访问限定符说明:

  1. public修饰的成员在类外
    可以直接被访问

  2. protected和private修饰的成员
    在类外不能直接被访问

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

  4. 如果后面没有访问限定符了
    作用域就一直到类结束

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

举例说明:

class NEO
{
public:
	void test1()
	{
		cout<<"haha";
	}

	void test2()
	{
		cout<<"hehe";
	}

private:
	int a;
	char b[20];
	double c;
}

int main()
{
	NEO tmp;
	tmp.test1();//正常运行
	tmp.a = 10;//运行报错
	tmp.c = 20;//运行报错
	return 0;
}

此类中,public和private
之间的成员是共有的,类外可以访问
private到类结束的成员是私有的
类外不能访问!

需要注意的点:

不管成员函数是共有还是私有
也不管成员变量是共有还是私有
成员函数都可以访问到成员变量!


5. 类的实例化

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

在实例化类对象之前,这个类并不占用内存

比如:

class Person
{
public:
	void printper()
	{
		cout<<name;
	}
private:
	char* name;
};

int main()
{
	Person.name = "NEO";//编译报错,还没有实例化对象
	Person p1;
	return 0;
}

若没有实例化对象p1
这个class类是不会开辟空间的!

class类就像一个设计图纸一样
在按照这个图纸建设房子前
这块区域是没有空间占用的
实例化对象就像按照图纸修房子一样
会占用空间

在这里插入图片描述


6. 类对象模型

怎么计算一个class类的大小?

例如:下面这两个类:

class A
{
	void PrintA()
	{
		cout << a << endl;
	}
	int a;
	char b;
};

class B
{
	int a;
	char b;
};

int main()
{
	printf("类A的大小: %d\n", sizeof(A));
	printf("类B的大小: %d\n", sizeof(B));
	return 0;
}

在这里插入图片描述

结论:

  1. 类中的成员函数不算在类的大小中
  2. 类的大小遵守结构体内存对齐规则
  3. 空类(没有成员变量)的大小是1字节

注:如果你不知道结构体内存对齐规则
请点击:结构体内存对齐规则


6.1 类对象的存储模式

为啥类中的成员函数不占空间?
那函数存储在什么位置?

带着这样的疑惑来看看类的存储模式:

  • 类成员变量存储在实例化对象中
  • 类成员函数存储在公共的代码段

可以用下面这张图来理解:

在这里插入图片描述

对类成员变量的解释:

由于每一个对象中的变量的值可能不同
所以成员变量存储在不同的对象中

对类成员函数的解释:

但是每个对象调用的函数是相同的
为了节省空间,将成员函数从对象中剥离
到公共代码段,不管实例化多少个对象
只要调用成员函数就会去代码段找!


7. this指针

先看以下的日期类:

class Date
{ 
public:
	void Init(int year, int month, int day)
	{
 		_year = year;
	 	_month = month;
	    _day = day;
    }
private:
 	int _year;     // 年
	int _month;    // 月
	int _day;      // 日
};

int main()
{
	Date d1;
	d1.Init(2023,7,22);//初始化对象
	return 0;
}

看似Init只有三个参数
看似调用Init时只传了三个参数

但其实还有一个隐藏的指针this!

可以用下图理解this的位置:

在这里插入图片描述

并且在每一个成员变量之前
都有this指针解引用访问它:

在这里插入图片描述


7.1 this指针的特性

基本特性:

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

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

  3. this指针不能我们显示去写
    也不能我们显示去传对象地址

  4. this指针存储在栈区,不存储在对象中

对特性的理解:

不能这样写代码:

class A
{ 
void Init(A* this,int a)
{
	_a=a;
}
 int _a;
};

int main()
{
	A a1;
	a1(&a,10);
}

假如这样写代码,那么函数参数就有三个
系统还是会自动传this指针,会报错


7.2 this指针的用处

假设我们实例化了两个对象
分别是d1和d2

class Date
{ 
public:
	void Init(int year, int month, int day)
	{
 		_year = year;
	 	_month = month;
	    _day = day;
    }
private:
 	int _year;     // 年
	int _month;    // 月
	int _day;      // 日
};

int main()
{
	Date d1;
	Date d2;
	d1.Init(2023,7,22);//初始化对象
	d2.Init(2023,7,23);
	return 0;
}

已知成员函数是放在公共代码段的
假如没有this指针存在
函数体又没有区别不同对象的手段

那么就会出现一个问题:
对象d1调用函数Init时,函数不知道是
哪一个对象调用了它,就无法区分对象

使用this指针将对象的地址传入函数中
函数体就可以区分不同对象了!


8. 总结以及拓展

本章是类和对象的入门篇
只介绍了类的解基本概念和特性
其中比较重要的是this指针
它还会陪伴我们很久!

基础不牢,地动山摇
类学不会,学C++就受罪

在这里插入图片描述

拓展: C++命名方式

C++又很多习惯的命名方式
这里介绍一个:驼峰法命名

  • 单词和单纯之间首字母大写
  • 函数名,类名首字母大写
  • 变量首字母小写,后面单词首字母大写
  • 成员变量的首字母前加下划线_

举例说明:

class Date
{ 
public:
  void InitDate(int year, int month, int day)//initialize date
  {                                          //初始化日期,简写后,I和D要大写
    _year = year;
    _month = month;
    _day = day;
  }
  void PrintInfo()//printf information,简写后P和I要大写
  {
    cout <<_year<< "-" <<_month << "-"<< _day <<endl;
  }
private:
  int _year; //成员变量前面加_
  int _month;
  int _day;     
};

🔎 下期预告:类和对象(中) 🔍

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

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

相关文章

代码随想录-回溯(组合问题)|ACM模式

目录 前言&#xff1a; 77.组合 题目描述&#xff1a; 输入输出示例&#xff1a; 思路和想法&#xff1a; 216. 组合总和 III 题目描述&#xff1a; 输入输出示例&#xff1a; 思路和想法&#xff1a; 17. 电话号码的字母组合 题目描述&#xff1a; 输入输出描述&a…

MODBUS TCP转CCLINK IE协议网关profinet接口和以太网接口的区别

你是否曾经遇到过需要将不同的设备连接到一个统一的网络中&#xff1f;或者你是否曾经遇到过设备之间的通讯协议不兼容的问题&#xff1f;远创智控的YC-CCLKIE-TCP通讯网关就是为解决这些问题而设计的。 YC-CCLKIE-TCP通讯网关是一款自主研发的CCLINK IE FIELD BASIC从站功能…

OpenAI报错 time out:HTTPSConnectionPool(host=‘api.openai.com‘, port=443)

项目场景&#xff1a; 使用openai的api调用chatGPT报错&#xff0c;同样的代码在另一台机器没有问题 问题描述 使用官方示例 import openaiopenai.api_key sk-xxxx def chat_gpt(prompt):prompt promptmodel_engine "text-davinci-003"completion openai.Comp…

【Default config not found for ApplicationConfig】的一种解决方案

&#x1f4a7; 记录一下今天遇到的 b u g \color{#FF1493}{记录一下今天遇到的bug} 记录一下今天遇到的bug&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &#x1f984; 个人主页——微风撞见云的博客&#x1f390; &#x1f433; 《数据结构与算…

vue项目之《 搭建路由系统 》

author&#xff1a;德玛玩前端 date&#xff1a;2023-07-22 今天&#xff0c;在工作中拿到了架构师的前端框架&#xff0c;是一个vue2elementui搭建的单页面架构&#xff0c;没有路由系统&#xff0c;需要自己搭建&#xff0c;因为以往拿到的框架都是路由系统已经搭建好&#x…

数据结构初阶--单链表

目录 一.单链表的定义 二.单链表的分类 2.1.不带头结点的单链表 2.2.带头结点的单链表 三.单链表的功能实现 3.1.单链表的定义 3.2.单链表的打印 3.3.单链表的结点的创建 3.4.单链表的尾插 3.5.单链表的头插 3.6.单链表的尾删 3.7.单链表的头删 3.8.单链表的查找 …

【Vue3】Vue3核心内容(上)

&#x1f380;个人主页&#xff1a;努力学习前端知识的小羊 感谢你们的支持&#xff1a;收藏&#x1f384; 点赞&#x1f36c; 加关注&#x1fa90; 文章目录 常用的Composition APIsetup函数ref函数reactive函数vue3中的响应式原理vue2的响应式Vue3的响应式 reactive对比Refse…

数据结构---手撕图解七大排序(含动图演示)

文章目录 插入排序直接插入排序希尔排序 选择排序选择排序堆排序 交换排序冒泡排序快速排序hoare版挖坑法前后指针法快速排序的递归展开图快速排序的优化三数取中法 快速排序的非递归实现 归并排序 插入排序 插入排序分为直接插入排序和希尔排序&#xff0c;其中希尔排序是很值…

xxl-job分布式任务调度器的学习

先看一下原生的任务调度器 package com.xxl.job.executor.service.jobhandler;import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component;Compone…

3.Docker网络和资源控制

文章目录 Docker操作二Docker网络实现原理端口映射查看日志 网络模式host模式container模式none模式bridge模式自定义网络 Docker资源控制CPU资源控制设置CPU使用率上限设置CPU资源占用比&#xff08;设置多个容器才有效&#xff09;设置容器绑定指定CPU 内存使用限制设置磁盘I…

RK3399移植u-boot

RK3399移植u-boot 0.前言一、移植1.交叉工具链安装2.获取bl31.elf3.移植u-boot1)下载&#xff1a;2)配置&#xff1a;修改串口波特率&#xff1a;修改emmc&#xff1a;配置FIT&#xff1a;配置boot delay&#xff1a;(可选) 3)编译&#xff1a;4)生成idbloader.img文件&#xf…

使用 Docker 快速上手中文版 LLaMA2 开源大模型

本篇文章&#xff0c;我们聊聊如何使用 Docker 容器快速上手朋友团队出品的中文版 LLaMA2 开源大模型&#xff0c;国内第一个真正开源&#xff0c;可以运行、下载、私有部署&#xff0c;并且支持商业使用。 写在前面 感慨于昨天 Meta LLaMA2 模型开放下载之后&#xff0c;Git…

实验五 分支限界法

实验五 分支限界法 01背包问题的分治限界法的实现 剪枝函数 限界函数 1.实验目的 1、理解分支限界法的剪枝搜索策略&#xff0c;掌握分支限界法的算法框架 2、设计并实现问题&#xff0c;掌握分支限界算法。 2.实验环境 java 3.问题描述 给定n种物品和一背包。物品i的重…

JMeter基础入门教程之CSV数据文件设置CSV Data Set Config

最近在做压力测试&#xff0c;登录功能用到了配置元件&#xff1a;CSV 数据文件设置&#xff0c;可以将登录用户名和密码放在一个csv文件中&#xff0c;然后通过CSV数据文件设置元件读取出来&#xff0c;用来做压测。 一、CSV文件 CSV文件小知识分享&#xff1a;是指"逗号…

Linux内核--内存管理

MMU的产生背景 在计算机出现的早期&#xff0c;其内存资源十分有限&#xff0c;一般只有几十几百KB&#xff0c;当时的程序规模也小&#xff0c;对于当时的程序而言&#xff0c;KB级的内存资源尚足够使用。但随着计算机技术的发展&#xff0c;应用程序的规模不断膨胀&#xff…

k8s部署wordpress+mysql博客平台

k8s部署wordpressmysql博客平台 1、yaml文件准备1.1 wordpress-db.yaml1.2 wordpress.yaml 2、部署安装2.1 先创建wordpress命名空间2.2 部署wordpress-db2.3部署wordpress 3、访问测试 1、yaml文件准备 1.1 wordpress-db.yaml apiVersion: apps/v1kind: Deploymentmetadata:…

【flink】ColumnarRowData

列式存储 在调试flink读取parquet文件时&#xff0c;读出来的数据是ColumnarRowData&#xff0c;由于parquet是列式存储的文件格式&#xff0c;所以需要用一种列式存储的表示方式&#xff0c;ColumnarRowData就是用来表示列式存储的一行数据&#xff0c;它包含多个数组的数据结…

Matlab求解基于RRT算法的自定义垛型的路径避障

目录 背景 1 RRT搜索算法 2 基于Matlab的RRT搜索算法 3 基于Matlab的自定义垛型绘制 4 基于RRT算法的自定义垛型的路径避障 背景 在码垛机械臂路径规划过程中&#xff0c;需要根据现有箱子的码垛状态&#xff0c;给出下一个箱子的最佳码放无碰撞路径。RRT 快速搜索随机…

vue2项目 自定义详情组件

vue2项目 自定义详情组件 效果组件代码组件引入以及传参格式寄语 效果 组件代码 DetailFormRow.vue已经封装好&#xff0c;根据数据格式直接引用即可。 <template><div class"detail-form"><el-row class"detail-form-row" style"ma…

基本函数、常见曲线图像

基本函数图像是指一些常见的数学函数的图像&#xff0c;这些函数在数学和工程等领域中经常被使用。下面是一些常见的基本函数及其图像&#xff1a; 参考文献&#xff1a;同济版高等数学【第七版】上下册教材