数组类模板(进阶版)

目录

介绍:

分析:

实现:

.hpp框架创建

.hpp函数内容

有参构造

拷贝构造:

重载=

插入数据

删除数据

通过下标访问

获取数组大小

获取数组容量

析构函数

.cpp框架

int类型数据测试

char类型测试

总代码

.hpp代码

.cpp代码


介绍:

简单实现版本在这里:数组类模板(类模拟实现静态数组)(简单版)-CSDN博客

简单版本分析了案例要求怎么实现,对该项目的实现的思路有帮助哦

分析:

* 因为不可能把所有代码放在源文件,所以要创建头文件---->存放类模板的相关信息
* 因为用了类模板,所以在调用时才给类分配内存,因此不可以写成:.h文件中为类模板的声       明,.cpp中为类模板的实现,会报错
创建.hpp文件存放类模板的声明和实现


实现:

.hpp框架创建

#pragma once/*头文件都要写这个哦,防止被重复包含,重复包含的弊端:编译阶段时编译器会将头文件全部展开放进源文件中,若重复包含,则头文件会被执行两次,占内存且耗时*/

#include <iostream>

using namespace std;

template<typename T>/*类模板*/
class MyArray
{
public:

private:
	T* pAddress;
	int m_Size;
	int m_Capacity;
};

.hpp函数内容

有参构造

	//有参构造
	MyArray(int capacity)
	{
		this->m_Capacity = capacity;
		this->m_Size = 0;
		
		pAddress = new T[capacity];
	}

拷贝构造:

	//拷贝构造
	MyArray(const MyArray& arr)
	{
		this->m_Capacity = arr.m_Capacity;
		this->m_Size = arr.m_Size;

		//浅拷贝
		//this->pAddress = arr.pAddress;

		//深拷贝
		this->pAddress = new T[m_Capacity];//注意时m_Capacity,而不是m_Size

		for (int i = 0; i < m_Size; i++)
			this->pAddress[i] = arr.pAddress[i];

	}
	

重载=

 	//重载=
	MyArray& operator=(const MyArray& arr)//注意返回类型,如果是void,则在a = b = c时会出错,因为改变的不是本身的数据,而是拷贝对象的数据
	{
		//如果堆区有数据,要先释放再拷贝
		if (pAddress != NULL)/**/
		{
			delete[] pAddress;
			pAddress = NULL;
			this->m_Capacity = 0;
			this->m_Size = 0;
		}

		this->m_Capacity = arr.m_Capacity;
		this->m_Size = arr.m_Size;
		this->pAddress = new T[m_Capacity];

		for (int i = 0; i < m_Size; i++)
			this->pAddress[i] = arr.pAddress[i];

		return *this;
	}

插入数据

 	//插入
	void MyInsert(T& e)
	{
		if (m_Size == m_Capacity)/**/
		{
			cout << "数组已存满" << endl;
			return;
		}

		this->pAddress[m_Size] = e;
		m_Size++;
	}

删除数据

	//删除
	void MyDelet()
	{
		if (m_Size == 0)
		{
			cout << "数组已为空" << endl;
			return;
		}

		m_Size--;
	}

通过下标访问

 	//通过下标访问
	//因为可能通过下标更改数据的值(a[0] = 100),所以要返回T&,  注意要是引用
	T& operator[](int idx)
	{
		return this->pAddress[idx];
	}

获取数组大小


	//获取数组大小
	int getSize()
	{
		return this->m_Size;
	}

获取数组容量

	//获取数组容量
	int getCapacity()
	{
		return this->m_Capacity;
	}

析构函数

	//析构函数
	~MyArray()
	{
		if (pAddress != NULL)/*防止重复释放*/
		{
			delete[] pAddress;
			pAddress = NULL;
			this->m_Capacity = 0;
			this->m_Size = 0;
		}
	}

.cpp框架

#include "shu_zu_lei_mu_ban.hpp"/*头文件名称*/
//自己创建的头文件用""访问更快,是直接去该文件路径下面查找文件
//用<>是直接库函数下查找文件,当要查找库中的文件时,用<>快

int main()
{
	return 0;
}

int类型数据测试

#include "shu_zu_lei_mu_ban.hpp"


//int数组
void PrintArr01(MyArray<int>& arr)
//注意参数中的类要写好类参数表<int>,因为类模板与函数模板不同,函数模板可以自动类型推导,而类模板不可
{
	int size = arr.getSize();
	for (int i = 0; i < size; i++)
	{
		cout << arr[i] << " ";
	}
	cout << endl;
}

void test01()
{
	MyArray<int>arr(10);

	//放入数据
	int size = arr.getCapacity();
	for (int i = 0; i < size; i++)
	{
		arr.MyInsert(i);
	}

	//打印数组
	PrintArr01(arr);
}


int main()
{
	test01();
	return 0;
}

char类型测试

#include "shu_zu_lei_mu_ban.hpp"


//char数组

void PrintArr02(MyArray<char>& arr)
{
	int size = arr.getSize();
	for (int i = 0; i < size; i++)
	{
		cout << arr[i] << " ";
	}
	cout << endl;
}

void test02()
{
	MyArray<char>arr(10);

	//放入数据
	arr.MyInsert('a');
	arr.MyInsert('c');
	arr.MyInsert('d');
	arr.MyInsert('e');


	//打印数组
	PrintArr02(arr);
}


int main()
{
	test02();
	return 0;
}

大家可以去自定义类测试,这里我就不陈述了

总代码

.hpp代码

#pragma once/**/

#include <iostream>

using namespace std;

template<typename T>
class MyArray
{
public:
	//有参构造
	MyArray(int capacity)
	{
		this->m_Capacity = capacity;
		this->m_Size = 0;
		
		pAddress = new T[capacity];
	}

	//拷贝构造
	MyArray(const MyArray& arr)
	{
		this->m_Capacity = arr.m_Capacity;
		this->m_Size = arr.m_Size;

		//浅拷贝
		//this->pAddress = arr.pAddress;

		//深拷贝
		this->pAddress = new T[m_Capacity];//注意时m_Capacity,而不是m_Size

		for (int i = 0; i < m_Size; i++)
			this->pAddress[i] = arr.pAddress[i];

	}
	 
	//重载=
	MyArray& operator=(const MyArray& arr)//注意返回类型,如果是void,则在a = b = c时会出错,因为改变的不是本身的数据,而是拷贝对象的数据
	{
		//如果堆区有数据,要先释放再拷贝
		if (pAddress != NULL)/**/
		{
			delete[] pAddress;
			pAddress = NULL;
			this->m_Capacity = 0;
			this->m_Size = 0;
		}

		this->m_Capacity = arr.m_Capacity;
		this->m_Size = arr.m_Size;
		this->pAddress = new T[m_Capacity];

		for (int i = 0; i < m_Size; i++)
			this->pAddress[i] = arr.pAddress[i];

		return *this;
	}

	//插入
	void MyInsert(T e)
	{
		if (m_Size == m_Capacity)
		{
			cout << "数组已存满" << endl;
			return;
		}

		this->pAddress[m_Size] = e;
		m_Size++;
	}

	//删除
	void MyDelet()
	{
		if (m_Size == 0)
		{
			cout << "数组已为空" << endl;
			return;
		}

		m_Size--;
	}

	//通过下标访问
	//因为可能通过下标更改数据的值(a[0] = 100),所以要返回T&,  注意要是引用
	T& operator[](int idx)
	{
		return this->pAddress[idx];
	}

	//获取数组大小
	int getSize()
	{
		return this->m_Size;
	}

	//获取数组容量
	int getCapacity()
	{
		return this->m_Capacity;
	}

	//析构函数
	~MyArray()
	{
		if (pAddress != NULL)/**/
		{
			delete[] pAddress;
			pAddress = NULL;
			this->m_Capacity = 0;
			this->m_Size = 0;
		}
	}
private:
	T* pAddress;
	int m_Size;
	int m_Capacity;
};

.cpp代码

#include "shu_zu_lei_mu_ban.hpp"


//int数组
void PrintArr01(MyArray<int>& arr)
{
	int size = arr.getSize();
	for (int i = 0; i < size; i++)
	{
		cout << arr[i] << " ";
	}
	cout << endl;
}

void test01()
{
	MyArray<int>arr(10);

	//放入数据
	int size = arr.getCapacity();
	for (int i = 0; i < size; i++)
	{
		arr.MyInsert(i);
	}

	//打印数组
	PrintArr01(arr);
}

//char数组

void PrintArr02(MyArray<char>& arr)
{
	int size = arr.getSize();
	for (int i = 0; i < size; i++)
	{
		cout << arr[i] << " ";
	}
	cout << endl;
}

void test02()
{
	MyArray<char>arr(10);

	//放入数据
	arr.MyInsert('a');
	arr.MyInsert('c');
	arr.MyInsert('d');
	arr.MyInsert('e');


	//打印数组
	PrintArr02(arr);
}


int main()
{
	//test01();
	test02();
	return 0;
}

题外话:

完结撒花~恭喜你又进步一点点啦~ 

如果你喜欢博主的话,用你的小手点点赞哦,点点收藏,如果想看博主的后序创作,可以点点关注哦

✨欢迎支持✨

      🎈创作不易,麻烦点点赞哦🎈

博主主页:脑子不好的小菜鸟

该文章专栏:项目_脑子不好的小菜鸟的博客-CSDN博客

文章特点:关键点和步骤讲解放在代码相应位置,大多为算法和刷题文章

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

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

相关文章

是德科技keysight N9000B 信号分析仪

181/2461/8938产品概述&#xff1a; 工程的内涵就是将各种创意有机地联系起来&#xff0c;并解决遇到的问题。 CXA 信号分析仪具有出色的实际性能&#xff0c;它是一款出类拔萃、经济高效的基本信号表征工具。 它的功能十分强大&#xff0c;为一般用途和教育行业的用户执行测试…

wireshark 使用

wireshark介绍 wireshak可以抓取经过主机网卡的所有数据包&#xff08;包括虚拟机使用的虚拟网卡的数据包&#xff09;。 环境安装 安装wireshark: https://blog.csdn.net/Eoning/article/details/132141665 安装网络助手工具&#xff1a;https://soft.3dmgame.com/down/213…

【LIMS】CMA与CNAS:中国认证体系中的两大支柱

目录 一、CMA&#xff1a;[中国计量认证](http://cma-cma.org.cn/)什么是CMA&#xff1f;CMA的作用 二、CNAS&#xff1a;[中国合格评定国家认可委员会](https://www.cnas.org.cn/)什么是CNAS&#xff1f;CNAS的作用 三、CMA与CNAS的关系相互促进共同目标 结语系列文章版本记录…

TCP网络协议栈和Posix网络部分API总结

文章目录 Posix网络部分API综述TCP协议栈通信过程TCP三次握手和四次挥手&#xff08;看下图&#xff09;三次握手常见问题&#xff1f;为什么是三次握手而不是两次&#xff1f;三次握手和哪些函数有关&#xff1f;TCP的生命周期是从什么时候开始的&#xff1f; 四次挥手通信状态…

git基本操作二(小白快速上手)

1、前言 接上篇我们接着来继续讲 2、.gitignore忽略文件 创建一个.gitignore文件&#xff0c;并将其置于项目的根目录下&#xff0c;Git将自动识别并根据该规则忽略相应的文件和目录。 # 忽略所有的 .log 文件 *.log# 但跟踪所有的 build.log 文件 !build.log# 忽略所有的 /lo…

lookup函数

lookup函数 单条件查询 示例 扩展多条件 扩展

文件的顺序读写——顺序读写函数——fgets、fgetc、fputs、 fputc

✨✨ 欢迎大家来到莉莉的博文✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 目录 一、fgetc和fputc函数 1.1 fputc 1.2 fgetc 二、fputs和fgets函数 2.1 fputs函数 2.2 fgets函数 一、fgetc和fputc函数 1.1 fputc 返回类…

结构体类型,结构体变量的创建和初始化 以及结构中存在的内存对齐

一般结构体类型的声明 struct 结构体类型名 { member-list; //成员表列 }variable-list; //变量表列 例如描述⼀个学⽣&#xff1a; struct Stu { char name[20]; //名字 int age; //年龄 char sex[5]; //性别 }&#xff1b; //结构体变量的初始化 int main() { S…

鸿蒙OS开发实例:【工具类封装-页面路由】

import common from ohos.app.ability.common; import router from ohos.router 封装app内的页面之间跳转、app与app之间的跳转工具类 【使用要求】 DevEco Studio 3.1.1 Release api 9 【使用示例】 import MyRouterUtil from ../common/utils/MyRouterUtil MyRouterUtil…

基于重写ribbon负载实现灰度发布

项目结构如下 代码如下&#xff1a; pom&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocat…

使用第三方远程连接工具ssh连接vagrant创建的虚拟机

vagrant默认密码都是vagrant 密码认证默认是关闭的&#xff0c;进入虚拟机&#xff0c;打开密码认证 1、使用命令vi /etc/ssh/sshd_config进入配置&#xff0c;注意要切换到root用户&#xff0c;这个配置root有权限 2、找到PasswordAuthentication默认为no,改为yes 3、重启虚…

ETL中RESTful API 组件的用法

一、ETL是什么 ETL&#xff0c;全称为Extract-Transform-Load&#xff0c;即数据提取&#xff08;Extract&#xff09;、数据转换&#xff08;Transform&#xff09;和数据加载&#xff08;Load&#xff09;。这是数据仓库中数据处理的重要过程。ETL过程中&#xff0c;数据从源…

小小狠招:巧妙使用HANA数据库的jdbc driver

SAP旗下的HANA数据库&#xff0c;实际上是分为两个系列进行发布&#xff0c;一种是基于本地部署的称之为HANA Platform。另一种是面向Cloud平台的&#xff0c;称之为HANA Cloud。 在实际使用当用&#xff0c;因为两者基本上共用同一代码库&#xff0c;除个别地方略有差异以外&…

【更清晰】照片分享,欢迎家庭新成员HPE ProLiant DL580 Gen9

正文共&#xff1a;1234 字 29 图&#xff0c;预估阅读时间&#xff1a;1 分钟 距离上一台服务器HPE ProLiant DL360 Gen9开箱已经过去4年了&#xff0c;回忆满满&#xff08;风雨同舟&#xff0c;感谢HP Proliant DL360 Gen9陪我走过的四年&#xff09;&#xff1b;就在上周&a…

相册清理大师-手机重复照片整理、垃圾清理软件

相册清理大师是一款超级简单实用的照片视频整理工具。通过便捷的操作手势&#xff0c;帮助你极速整理相册中的照片和视频、释放手机存储空间。 【功能简介】 向上滑动&#xff1a;删除不要的照片 向左滑动&#xff1a;切换下一张照片 向右滑动&#xff1a;返回上一张照片 整理分…

拌合楼管理软件开发(十三) 对接耀华XK3190-A9地磅(实战篇)

前言: 实战开整 目前而言对于整个拌合楼管理软件开发,因为公司对这个项目还处于讨论中,包括个人对其中的商业逻辑也存在一些质疑,都是在做一些技术上的储备.很早就写好了串口与地磅对接获取代码,也大概知道真个逻辑,这次刚好跟库区沟通,远程连接到磅房电脑,开始实操一下. 一、地…

Sql注入---基础

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一.Sql注入概述 攻击者通过构造恶意的SQL查询语句&#xff0c;将其注入到应用程序的数据库查询中&#xff0c;以执行未经授权的操作或者获取敏感信息。 假设如下场景&#xff0c;当你想要知道对…

双端队列的插入与删除操作的实现及其时间复杂度分析

双端队列(deque,全称为double-ended queue)是一种支持在两端插入和删除元素的数据结构。与栈和队列不同,双端队列提供了更加灵活的操作方式。在实现双端队列时,我们可以采用数组作为底层数据结构,以保证插入和删除操作的时间复杂度为O(1)。 一、双端队列的基本概念 双…

《QT实用小工具·四》屏幕拾色器

1、概述 源码放在文章末尾 该项目实现了屏幕拾色器的功能&#xff0c;可以根据鼠标指定的位置识别当前位置的颜色 项目功能包含&#xff1a; 鼠标按下实时采集鼠标处的颜色。 实时显示颜色值。 支持16进制格式和rgb格式。 实时显示预览颜色。 根据背景色自动计算合适的前景色…

Artplayer视频JSON解析播放器源码|支持弹幕|json数据模式

全开源Artplayer播放器视频解析源码&#xff0c;支持两种返回模式&#xff1a;网页播放模式、json数据模式&#xff0c;json数据模式支持限制ip每分钟访问次数UA限制key密钥&#xff0c;也可理解为防盗链 &#xff0c;本播放器带弹幕库。 运行环境 推荐使用PHP8.0 redis扩展…