C++实现一个存储内置数据类型和自定义数据类型的通用数组类

news2024/9/9 0:29:49

C++实现一个存储内置数据类型和自定义数据类型的通用数组类

    • 需求
    • 自定义数组类MyArray
    • 拷贝构造函数,重写operator=函数
    • 尾插法和尾删法
    • 通过下标访问
    • 获取数组大小和容量
    • 全部代码

需求

通用的数组类,
1、内置数据类型以及自定义数据类型进行存储
2、数组中的数据存储到堆中
3、构造函数中可以传入数组的容量
4、拷贝构造函数,operator=防止浅拷贝
5、尾插法和尾删法
6、下标访问
7、获取数组中当前元素个数和数组的容量

自定义数组类MyArray

#pragma once
#include <iostream>
using namespace std;


template <class T>
class MyArray
{
public:
	//有参构造 初始容量
	MyArray(int capacity) {
		cout << "调用MyArray有参构造" << endl;
		this->m_Capacity = capacity;
		this->m_Size = 0;
		this->pAddress = new T[this->m_Capacity];
	}
	
	//析构函数,数据释放
	~MyArray() {
		cout << "调用MyArray析构函数" << endl;
		if (this->pAddress != NULL) {
			delete[] pAddress;
			this->pAddress = NULL;
		}
	}

private:
	T * pAddress;//数组指针,用于存放数据
	int m_Size;//数组当前大小
	int m_Capacity;//容量
};





拷贝构造函数,重写operator=函数

//拷贝函数
MyArray(const MyArray& arr) {
	cout << "调用MyArray拷贝构造函数" << endl;
	this->m_Capacity = arr.m_Capacity;
	this->m_Size = arr.m_Size;
	//
	this->pAddress = new T[arr.m_Capacity];
	for (int i = 0; i < this->m_Size; i++)
	{
		this->pAddress[i] = arr.pAddress[i];
	}

}

//operator= 防止浅拷贝操作,返回自身的引用,
MyArray& operator=(const MyArray& arr)
{
	cout << "调用MyArrayoperator=函数" << endl;
	//先判断原来的堆区是否有数据,有数据释放
	if (this->pAddress != NULL)
	{
		delete[] pAddress;
		this->pAddress = NULL;
		this->m_Capacity = 0;
		this->m_Size = 0;
	}
	this->m_Capacity = arr.m_Capacity;
	this->m_Size = arr.m_Size;
	for (int i = 0; i < this->m_Size; i++)
	{
		this->pAddress[i] = arr[i];
	}
	return this;
}

尾插法和尾删法

//尾插法
void add(const T& val) {
	if (this->m_Size < this->m_Capacity)
	{

		this->pAddress[this->m_Size] = val;
		this->m_Size++;
	}
	else
	{
		//扩容
		Expansion();
		this->pAddress[this->m_Size] = val;
		this->m_Size++;
	}
}

//尾删法
void Pop_Back() {
	if (this->m_Size == 0) {
		return;
	}
	this->pAddress[m_Size - 1] = this->pAddress[m_Size];
	this->m_Size--;
}

//扩容
void Expansion() {
	T* newpAddress = new T[this->m_Capacity << 2];
	for (int i = 0; i < this->m_Size; i++)
	{
		newpAddress[i] = this->pAddress[i];
	}
	//释放原数组内存
	delete[] this->pAddress;
	//指针指向新数组
	this->pAddress = newpAddress;
	this->m_Capacity *= 2;
}

通过下标访问

//通过下标访问   &,返回可以作为左值
T& operator[](int index) {
	return this->pAddress[index];
}

获取数组大小和容量

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

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

全部代码

#pragma once
#include <iostream>
using namespace std;


template <class T>
class MyArray
{
public:
	//有参构造 初始容量
	MyArray(int capacity) {
		cout << "调用MyArray有参构造" << endl;
		this->m_Capacity = capacity;
		this->m_Size = 0;
		this->pAddress = new T[this->m_Capacity];
	}
	//拷贝函数
	MyArray(const MyArray& arr) {
		cout << "调用MyArray拷贝构造函数" << endl;
		this->m_Capacity = arr.m_Capacity;
		this->m_Size = arr.m_Size;
		//
		this->pAddress = new T[arr.m_Capacity];
		for (int i = 0; i < this->m_Size; i++)
		{
			this->pAddress[i] = arr.pAddress[i];
		}

	}

	//operator= 防止浅拷贝操作,返回自身的引用,
	MyArray& operator=(const MyArray& arr)
	{
		cout << "调用MyArrayoperator=函数" << endl;
		//先判断原来的堆区是否有数据,有数据释放
		if (this->pAddress != NULL)
		{
			delete[] pAddress;
			this->pAddress = NULL;
			this->m_Capacity = 0;
			this->m_Size = 0;
		}
		this->m_Capacity = arr.m_Capacity;
		this->m_Size = arr.m_Size;
		for (int i = 0; i < this->m_Size; i++)
		{
			this->pAddress[i] = arr[i];
		}
		return this;
	}

	//尾插法
	void add(const T& val) {
		if (this->m_Size < this->m_Capacity)
		{

			this->pAddress[this->m_Size] = val;
			this->m_Size++;
		}
		else
		{
			//扩容
			Expansion();
			this->pAddress[this->m_Size] = val;
			this->m_Size++;
		}
	}

	//尾删法
	void Pop_Back() {
		if (this->m_Size == 0) {
			return;
		}
		this->pAddress[m_Size - 1] = this->pAddress[m_Size];
		this->m_Size--;
	}

	//自动扩容
	void Expansion() {
		this->m_Capacity << 2;
		T* newpAddress = new T[this->m_Capacity];
		for (int i = 0; i < this->m_Size; i++)
		{
			newpAddress[i] = this->pAddress[i];
		}
		//释放原数组内存
		delete[] this->pAddress;
		//指针指向新数组
		this->pAddress = newpAddress;
		this->m_Capacity *= 2;
	}

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

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

	

	

	//通过下标访问   &,返回可以作为左值
	T& operator[](int index) {
		return this->pAddress[index];
	}

	



	//析构函数,数据释放
	~MyArray() {
		cout << "调用MyArray析构函数" << endl;
		if (this->pAddress != NULL) {
			delete[] pAddress;
			this->pAddress = NULL;
		}
	}

private:
	T * pAddress;//数组指针
	int m_Size;//数组大小
	int m_Capacity;//容量
};

测试代码:

```#include <iostream>
#include "MyArray.hpp"
//直接包含源文件
using namespace std;

void showArray(MyArray<int> &p) {
	for (int i = 0; i < p.getSize(); i++)
	{
		cout << p[i]<<" ";
	}
	cout<<endl;
}

class Hero
{
public:
	Hero() {};
	Hero(string name,int age) {
		this->m_Name = name;
		this->m_Age = age;
	};
	~Hero() {
	};
	string m_Name;
	int m_Age;
};

void showHeroArray(MyArray<Hero>& arr) {
	for (int i = 0; i < arr.getSize(); i++)
	{
		cout << "姓名:" << arr[i].m_Name << "   年龄:" << arr[i].m_Age << endl;
	}
}



int main() {
	MyArray<int> arr(1);
	cout << "数组容量" << arr.getCapacity() << endl;
	cout << "数组大小" << arr.getSize() << endl;
	arr.add(1);
	arr.add(2);
	arr.add(2);
	arr.add(2);
	cout << "数组容量" <<arr.getCapacity() << endl;
	cout << "数组大小" <<arr.getSize() <<endl;
	showArray(arr);
	arr.Pop_Back();
	cout << "删除尾元素" << endl;
	cout << "数组容量" << arr.getCapacity() << endl;
	cout << "数组大小" << arr.getSize() << endl;
	showArray(arr);

	MyArray<Hero> hArr(5);
	hArr.add(Hero("张三", 100));
	hArr.add(Hero("李四", 100));
	hArr.add(Hero("王五", 100));
	hArr.add(Hero("赵六", 100));
	hArr.add(Hero("田七", 100));

	showHeroArray(hArr);
	
	return 0;
}

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

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

相关文章

【数据结构】队列(链表实现 + 力扣 + 详解 + 数组实现循环队列 )

Hi~&#xff01;这里是奋斗的明志&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f331;&#x1f331;个人主页&#xff1a;奋斗的明志 &#x1f331;&#x1f331;所属专栏&#xff1a;数据结构 &#x1f4da;本系列文章为个人学…

流行巨星布兰妮·斯皮尔斯发生了什么事?她现在在哪里过得怎么样

流行音乐公主布兰妮斯皮尔斯是 21 世纪初的经典偶像。她从 15 岁起就开始唱歌和表演&#xff0c;并创作了《Oops I Did it Again》和《Baby One More Time》等热门歌曲。她的歌曲非常出色&#xff0c;在 2000 年荣登榜首。她接下来的几张专辑变得更加畅销&#xff0c;她毫不畏惧…

学习008-02-04-04 Enable Split Layout in a List View(在列表视图中启用拆分布局 )

Enable Split Layout in a List View&#xff08;在列表视图中启用拆分布局 &#xff09; This lesson explains how to enable a Split Layout in a List View. 本课介绍如何在列表视图中启用拆分布局。 The Detail View opens when you select an object from the List Vie…

G120 EPos配置方案及应用场景

EPos功能就是基本定位器功能,它可计算出轴的运行特性,使轴以时间最佳的方式移动到目标位置。EPos功能主要包括:设定值 直接给定(MDI)功能、 选择程序段功能、回参考点功能、点动功能、运行到固定挡块功能。 EPos功能通过处理给定的加速度、速度和位置值生成运行特性曲线,…

node+mysql+layui+ejs实现左侧导航栏菜单动态显示

nodemysqllayuiejs实现左侧导航菜单动态显示 实现思路效果图数据库技术栈代码实现main.html&#xff08;前端首页页面&#xff09;查询资源菜单方法 jsapp.js配置ejs模板 node入门到入土项目实战开始&#xff0c;前端篇项目适合node小白入门&#xff0c;因为我也是小白来学习no…

机器人笛卡尔空间阻抗控制

机器人笛卡尔空间阻抗控制是一种重要的机器人控制策略,它关注于机器人末端执行器在笛卡尔空间(即任务空间)内的动态特性,以实现与环境的柔顺交互。以下是对机器人笛卡尔空间阻抗控制的详细解释: 一、基本概念 笛卡尔空间:指机器人末端执行器(如手爪、工具等)所处的三维…

Hive之扩展函数(UDF)

Hive之扩展函数(UDF) 1、概念讲解 当所提供的函数无法解决遇到的问题时&#xff0c;我们通常会进行自定义函数&#xff0c;即&#xff1a;扩展函数。Hive的扩展函数可分为三种&#xff1a;UDF,UDTF,UDAF。 UDF&#xff1a;一进一出 UDTF&#xff1a;一进多出 UDAF&#xff1a…

YOLO v8目标检测(三)模型训练与正负样本匹配

YOLO v8目标检测 损失函数理论 在YOLO v5模型中&#xff0c;cls, reg, obj代表的是三个不同的预测组成部分&#xff0c;对应的损失函数如下&#xff1a; cls: 这代表类别预测&#xff08;classification&#xff09;。对应的损失是类别预测损失&#xff08;loss_cls&#xff…

Win10出现错误代码0x80004005 一键修复指南

对于 Windows 10 用户来说&#xff0c;错误代码 0x80004005 就是这样一种迷雾&#xff0c;它可能在不经意间出现&#xff0c;阻碍我们顺畅地使用电脑。这个错误通常与组件或元素的缺失有关&#xff0c;它可能源自注册表的错误、系统文件的损坏&#xff0c;或者是软件的不兼容。…

listener监听

背景: 过滤器代码也可实现接口请求次数统计,但会影响过滤器本意;故在dispatcher servlet层进行监听统计 价值: 所有接口的次数统计可适用于系统全天访问量; 单个请求接口的次数统计可在企业中根据接口次数的高低,可分析出接口对应的功能受用户的喜好程度 请求通过过滤器到了s…

common-intellisense:助力TinyVue 组件书写体验更丝滑

本文由体验技术团队Kagol原创~ 前两天&#xff0c;common-intellisense 开源项目的作者 Simon-He95 在 VueConf 2024 群里发了一个重磅消息&#xff1a; common-intellisense 支持 TinyVue 组件库啦&#xff01; common-intellisense 插件能够提供超级强大的智能提示功能&…

c生万物系列(职责链模式与if_else)

从处理器的角度来说&#xff0c;条件分支会导致指令流水线的中断&#xff0c;所以控制语句需要严格保存状态&#xff0c;因为处理器是很难直接进行逻辑判断的&#xff0c;有可能它会执行一段时间&#xff0c;发现出错后再返回&#xff0c;也有可能通过延时等手段完成控制流的正…

skynet 实操篇

文章目录 概述demo启动文件skynet_start配置文件main.luastart函数thread_workerskynet_context_message_dispatchskynet_mq_popdispatch_message 小结 概述 上一篇写完skynet入门篇&#xff0c;这一篇写点实操性质的。 demo 对于一个开源框架&#xff0c;大部分都有他们自己…

《Linux运维总结:基于x86_64架构CPU使用docker-compose一键离线部署zookeeper 3.8.4容器版分布式集群》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;《Linux运维篇&#xff1a;Linux系统运维指南》 一、部署背景 由于业务系统的特殊性&#xff0c;我们需要面对不同的客户部署业务系统&#xff0…

C++客户端Qt开发——界面优化(美化登录界面)

美化登录界面 在.ui中拖入一个QFream&#xff0c;顶层窗口的QWidget无法设置背景图片&#xff0c;套上一层QFrame将背景图片设置到QFrame上即可 用布局管理器管理元素&#xff1a;用户名LineEdit&#xff0c;密码LineEdit&#xff0c;记住密码ComboBox&#xff0c;登录Button…

ubuntu2204安装elasticsearch7.17.22

下载安装 wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.22-amd64.deb wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.22-amd64.deb.sha512 shasum -a 512 -c elasticsearch-7.17.22-amd64.deb.sha512 su…

web、http协议、apache服务、nginx服务

web基本概念和常识 概念 web&#xff1a;为用户提供的一种在互联网上浏览信息的服务&#xff0c;是动态的、可交互的、跨平台的和图形化的&#xff1b; 为用户提供各种互联网服务&#xff0c;这些服务包括浏览服务以及各种交互式服务&#xff0c;包括聊天、购物等&#xff1…

windows下,pyrouge安装教程

1.安装perl 1.1 在命令行&#xff0c;检查perl是否安装 perl-v 1.2 安装perl 下载地址 Strawberry Perl for Windows - Releases 1&#xff09;下载msi版本 2&#xff09;双击安装包&#xff0c;傻瓜式安装&#xff0c;一路next&#xff0c;&#xff08;可修改安装路径&am…

Matlab编程资源库(16)数值微分

一、数值差分与差商 在Matlab中&#xff0c;数值差分与差商是数值分析中常用的概念&#xff0c;尤其在求解微分方程、插值、逼近等领域有广泛应用。下面简要介绍这两个概念及其在Matlab中的实现。 数值差分 数值差分是微分运算的离散化形式&#xff0c;用于近似求解导数。给定…

宠物浮毛空气净化器真的有用吗?性价比高的浮毛空气净化器推荐

作为一位5年资深铲屎官&#xff0c;随着养猫的家庭数量不断增加&#xff0c;轻松撸猫虽然很快乐。然而&#xff0c;宠物的存在也可能引发一些问题&#xff0c;比如宠物的体味和脱落的毛发&#xff0c;这些都可能成为影响家庭健康的隐患。特别是宠物排泄物的气味&#xff0c;如果…