【C++】--类与对象(1)

news2024/11/25 20:21:25

🧇个人主页: 起名字真南
🌭个人专栏:【数据结构初阶】 【C语言】 【C++】
请添加图片描述

目录

  • 1 类的定义
    • 1.1 类定义格式
      • 1.1.1 Stack类
      • 1.1.2 Date类
      • 1.1.3 Struct格式
    • 1.2 访问限定符
    • 1.3 类域
  • 2 实例化
    • 2.2 对象大小
  • 3 this指针

1 类的定义

1.1 类定义格式

1 class为定义类的关键字,Stack为类的名字,{}内为类的主体,并且类在定义的时候不能省略后面的分号,类体中的内容称为类的成员,类中的变量叫做类的属性,也被称为成员变量,类中的函数叫做类的方法也被称为成员函数
2 为了区分成员变量和全局变量以及主函数之间的变量在类中定义成员变量的时候可以加上下划线 ‘ _ ’
3 C++中struct也可以定义类,并且C++兼容C语言中struct结构体的用法,并且升级为类,最大的区别便是可以在内部定义函数。
4 定义在类中的成员函数默认为inline

1.1.1 Stack类

#include<iostream>
using namespace std;
#include<assert.h>

class Stack
{
public:
	//成员函数
	void Init(int n )
	{
		arr = (int*)malloc(sizeof(int) * n);
		if (arr == nullptr)
		{
			perror("开辟空间出现错误!");
			return;
		}
		capacity = n;
		top = 0;
	}

	void Push(int x)
	{
		arr[top++] = x;
	}

	int Top()
	{
		assert(arr);
		return arr[top - 1];
	}

	void Destroy()
	{
		free(arr);
		capacity = 0;
		top = 0;
	}

private:
	int* arr;
	size_t capacity;
	size_t top;
};

int main()
{
	Stack st1;
	st1.Init(4);
	st1.Push(1);
	st1.Push(2);
	st1.Push(3);
	st1.Push(4);
	cout << st1.Top() << endl;
	return 0;
}

1.1.2 Date类

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(2024, 9, 20);

	return 0;
}

在这里插入图片描述

1.1.3 Struct格式

#include<iostream>
using namespace std;
#include<assert.h>

//C语言环境下struct的定义
typedef struct ListNodeC
{
	ST* next;
	// struct ListNode* next;
	int val;
}ST;

struct ListNodeCpp
{
	void Init(int x)
	{
		next = nullptr;
		val = 0;
	}
	ListNodeCpp* next;
	int val;
};

在C++中不需要typedef只需要ListNodeCpp就可以代表这个类型,并且在struct类下里面的成员函数和成员变量默认的访问权限都是public。

1.2 访问限定符

  • C++实现封装的一种方式,就是用类把成员变量和成员函数结合在一块,然后通过访问权限选择性的将接口提供给外部的用户进行使用
  • public修饰的成员变量和函数是可以被任意访问的但是用private/protected修饰的则不能直接进行访问
  • class类在默认的情况下都是用private来修饰,struct在默认的情况下都是public
  • 访问限定符的权限以及作用范围都是从第一个访问限定符开始到第二个访问限定符之前,或者直接到 “ } ”。

1.3 类域

  • 类定义了一个新的作用域,类的所有成员都在类的作用域中,在类体外定义成员变量的时候需要使用 “::” 作用域操作符来指定该成员属于那个类域
  • 类域影响的是编译的查找规则,例如在下面的代码中如果在定义函数Init的时候没有指定类域就会出现访问不到Stack类中数据的错误,如果不指定类域那么Init就会被编译器认为是全局函数找不到类中的成员变量。
#include<iostream>
using namespace std;

class Stack
{
public:
	void Init(int n = 4);


private:
	int* array;
	size_t capacity;
	size_t top;
};
//声明和定义分离要指定类域
void Stack::Init(int n)
{
	array = (int*)malloc(sizeof(int) * n);
	if (array == nullptr)
	{
		perror("malloc fail");
		return;
	}
	capacity = n;
	top = 0;
}
int main()
{
	Stack st;
	st.Init();
	return 0;
}

在这里插入图片描述

2 实例化

  • 用类类型在物理内存中创建对象的过程叫做实例化对象。
  • 在类中的成员变量只是声明,并没有分配出空间,通过类进行实例化的对象才会分配空间
  • 一个类可以实例化出多个对象,实例化出来的对象占用实际的物理内存空间,存储成员变量。
class Date
{
public:
	void Init(size_t year = 2024, size_t month = 10, size_t day = 5)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}

private:
	//只有声明,并没有分配空间
	size_t _year;
	size_t _month;
	size_t _day;
};
int main()
{
	//实例化出两个对象 d1 d2 
	Date d1;
	d1.Init();
	d1.print();
	Date d2;
	d2.Init(1000,10,10);
	d2.print();
	return 0;
}

2.2 对象大小

内存对齐规则

  1. 第一个成员在与结构体偏移量为0的地址处
  2. 其他成员变量要对齐到对齐数的整数倍的地址处
  3. 对齐数 = 编译器默认的对齐数和成员变量大小的较小值
  4. vs中默认对齐数的大小是8
  5. 结构体的总大小为:最大对齐数(所有变量类型最大者与默认对齐数取最小)的整数倍
  6. 如果嵌套了结构体的情况下,嵌套的结构体对齐到自己最大对齐数的整数倍,整个结构体的大小就是所有最大对齐数的整数倍.
class A
{
public:
	void Init()
	{

	}
private:
	char _ch;
	int _i;
};
class B
{
public:
	void Init()
	{

	}

};
class C
{

};
int main()
{
	A a;
	B b;
	C c;
	cout << sizeof(a) << endl;
	cout << sizeof(b) << endl;
	cout << sizeof(c) << endl;
	return 0;
}

将上面的代码运行结果展示
在这里插入图片描述

我们可以看到输出的结果是 8 1 1,说明a b c 的大小分别是 8 1 1,那么这个结果是怎么算出来的呢?

在A类型中最大对齐数为4,是整形int的大小,A中有两个类型另一个是char,char的大小是一个字节,int是四个字节加起来就是五个字节,4的整数倍是8正好大于5所以a对象的大小就是8,但是B C 的大小为什么是1呢?为什么没有成员变量还还有一个字节呢,其实这里的一个字节仅表示该类型存在纯粹是为了占位标识对象存在。

3 this指针

  • 在Date类中有 Init 和 print两个成员函数,函数体中没有关于不同函数的区分但是我们在对d1 和d2两个对象进行初始化的时候是如何进行区分的呢?解决问题的方法就是在C++中提供了this指针。
  • 编译器编译后,都会默认在类的成员函数的形参前面添加一个当前类类型的this指针,比如Date类中的Init成员函数的原型是:void Init(Date const this, int year, int month, int day)*
  • 类中的成员函数访问成员变量本质上都是通过this指针进行访问的比如在Init中给year赋值本质上是:this->_year = year
  • C++规定不能在实参和形参的位置上显示写this指针但是可以在函数体内显示使用this指针
class Date
{
public:
	// void Init (const Date* this, size_t year, size_t month, size_t day)
	void Init(size_t year = 2024, size_t month = 10, size_t day = 5)
	{
		this->_year = year;
		this->_month = month;
		this->_day = day;
	}
	void print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}

private:
	//只有声明,并没有分配空间
	size_t _year;
	size_t _month;
	size_t _day;
};

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

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

相关文章

软件设计之SSM(5)

软件设计之SSM(5) 路线图推荐&#xff1a; 【Java学习路线-极速版】【Java架构师技术图谱】 尚硅谷新版SSM框架全套视频教程&#xff0c;Spring6SpringBoot3最新SSM企业级开发 资料可以去尚硅谷官网免费领取 学习内容&#xff1a; AOP面向切面编程 代理AOP面向切面编程获取…

好用的股票预测八大算法的Python实现

股票预测算法通常涉及时间序列分析、统计学、机器学习和深度学习等多种方法。以下是经典的、常见的十大股票预测算法及其Python实现。这些算法各有优势&#xff0c;可以用于不同的市场预测场景。以下代码实现中&#xff0c;我们将使用yfinance下载数据&#xff0c;并展示各算法…

如何创建商业博客:一步一步教你从零开始

搭建一个成功的商业博客&#xff0c;不仅可以提升品牌形象&#xff0c;还能吸引更多潜在客户。作为一个在这方面有些经验的人&#xff0c;我来分享一些实用的步骤和建议&#xff0c;希望对你有所帮助。 一、明确你的目标和客户群体 确定目标&#xff1a;首先&#xff0c;你得搞…

Origin图像中插入各种符号以及矩形椭圆等

画各种形状 空白处右击 文字处右击

【RISCV指令集手册】向量扩展v1.0

概述 从rvv 0.9说起 此前写过向量扩展0.9的阅读记录&#xff0c;三年已过&#xff0c;本以为不再参与RVV的相关开发&#xff0c;奈何造化弄人&#xff0c;旧业重操&#xff0c;真就世事难料呀。 总的来说1.0版本相比0.9版本的扩充了较多内容&#xff0c;但大部分为指令功能的…

力扣1~5题

题1&#xff08;简单&#xff09;. 思路&#xff1a; 因为时间复杂度小于n^2,所以不能双for遍历&#xff0c;怎么优化&#xff1f; 这里采用一个键值对的形式&#xff0c;存储nums离target的间隔和它的下标&#xff0c;只要n&#xff0c;然后再遍历nums有没有刚好是这个距离的就…

cnn突破四(生成卷积核与固定核对比)

cnn突破三中生成四个卷积核&#xff0c;训练6万次&#xff0c;91分&#xff0c;再训练6万次&#xff0c;95分&#xff0c;不是很满意&#xff0c;但又找不到问题点&#xff0c;所以就想了个办法&#xff0c;使用三个固定核&#xff0c;加上三层bpnet神经网络&#xff0c;看看效…

从零开始学cv-16:超像素图像分割

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、超像素图像分割简介二&#xff1a;SLIC超像素图像分割三&#xff1a;Seed超像素分割算法四 &#xff1a;LSC超像素分割 前言 在数字图像处理和计算机视觉领…

2、Redis数据安全性分析

文章目录 一、Redis性能压测脚本介绍二、Redis数据持久化机制详解1、整体介绍Redis的数据持久化机制2、RDB详解3、AOF详解4、混合持久化策略 三、Redis主从复制Replica机制详解**1、Replica是什么&#xff1f;有什么用&#xff1f;****2、如何配置Replica&#xff1f;****3、如…

【AI知识点】正态分布(高斯分布)和中心极限定理(CLT)

正态分布&#xff08;Normal Distribution&#xff09;和中心极限定理&#xff08;Central Limit Theorem, CLT&#xff09; 是统计学中非常重要的概念&#xff0c;它们广泛应用于概率论、数据分析、机器学习等领域。以下将详细解释这两个概念及其关系。 1. 正态分布&#xff…

【C++】入门基础介绍(上)C++的发展历史与命名空间

文章目录 1. 前言2. C发展历史2. 1 C版本更新特性一览2. 2 关于C23的一个小故事: 3. C的重要性3. 1 编程语言排行榜3. 2 C在工作领域中的应用 4. C学习建议和书籍推荐4. 1 C学习难度4. 2 学习书籍推荐 5. C的第一个程序6. 命名空间6. 1 namespace的价值6. 2 namespace的定义6. …

《CUDA编程》4.CUDA程序的错误检测

在编写CUDA程序时&#xff0c;有的错误在编译过程中被发现&#xff0c;称为编译错误&#xff0c;有的在运行时出现&#xff0c;称为运行时刻错误&#xff0c;本章讨论如何排查运行时刻错误 1 一个检测CUDA运行时错误的宏函数 1.1 编写错误检查宏函数 在《CUDA编程》3.简单CUD…

从0到1:培训机构排课小程序开发笔记一

业务调研 随着人们生活水平的提高&#xff0c;健康意识和学习需求日益增强&#xff0c;私教、健身和培训机构的市场需求迅速增长。高效的排课系统不仅可以提升机构的管理效率&#xff0c;还能提高学员的满意度。解决传统的排课方式存在的时间冲突、信息不对称、人工操作繁琐等…

51单片机的家用煤气报警系统【proteus仿真+程序+报告+原理图+演示视频】

1、主要功能 该系统由AT89C51/STC89C52单片机LCD1602显示模块温度传感器CO传感器蓝牙LED、蜂鸣器等模块构成。适用于家用天然气泄露报警器、煤气泄露报警器、无线报警等相似项目。 可实现功能: 1、LCD1602实时显示温度和煤气浓度 2、温度传感器DS18B20采集环境温度 3、CO传…

【Mybatis篇】Mybatis的关联映射详细代码带练 (多对多查询、Mybatis缓存机制)

&#x1f9f8;安清h&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;【计算机网络】,【Mybatis篇】 &#x1f6a6;作者简介&#xff1a;一个有趣爱睡觉的intp&#xff0c;期待和更多人分享自己所学知识的真诚大学生。 目录 &#x1f3af;一.关联映射概述 &#x1f6a…

【BUG】P-tuningv2微调ChatGLM2-6B时所踩的坑

0.前言 P-tuning v2的实验在网上一抓一大把&#xff0c;这里就说一下我在微调过程中遇到的有些bug&#xff0c;踩过的一些坑&#xff0c;在网上找了很久都没有一些好的解决方案&#xff0c;在这里记录一下。 1.下载预训练模型 在官方给出的教程中&#xff0c;并不需要预先将模…

【springboot】简易模块化开发项目整合Swagger2

接上一项目【springboot】简易模块化开发项目整合MyBatis-plus&#xff0c;进行拓展项目 1.新建模块 右键项目→New→Module&#xff0c;新建一个模块 父项目选择fast-demo&#xff0c;命名为fast-demo-config&#xff0c;用于存放所有配置项 添加后&#xff0c;项目结构如图…

X3U·可编程控制器的定位控制

FX3U可编程控制器的定位控制进行说明。 一、概要 FX3U可编程控制器可以向伺服电机、步进电机等输出脉冲信号&#xff0c;从而进行定位控制。 脉冲频率高的时候&#xff0c;电机转得快:脉冲数多的时候&#xff0c;电机转得多。用脉冲频率、脉冲数来设定定位对象…

Linux基本命令及vim应用实训练习

Linux基本命令及vim应用实训练习 1. 2. 3. 4. 5. 使用man cp找出

4 思科模拟器的介绍和使用

4 思科模拟器的介绍和使用 思科的IOS给我们提供了三大模式 设备开机后&#xff0c;进入的模式是【用户模式】 Router表示设备的名称 “>”表示用户模式 在用户模式输入"?" 可列出在用户模式可以使用的命令 第二种模式是特权模式,输入enable进入特权模式&…