C++之模拟ArrayList的操作(模板的使用)

Posted 你是小KS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++之模拟ArrayList的操作(模板的使用)相关的知识,希望对你有一定的参考价值。

1.声明

当前内容主要为本人学习C++的操作,主要为模拟Java中的ArrayList的基本操作

主要有

  1. 实现添加数据
  2. 删除数据
  3. 自动扩容为原来的1.5倍
  4. 使用模板创建类
  5. 自定义异常类

2.基本的demo

1.ArrayList.h文件内容

/*
 * ArrayList.h
 *
 *  Created on: 2021年5月4日
 *      Author: hy
 */

#ifndef TEMPLATE_ARRAYLIST_H_
#define TEMPLATE_ARRAYLIST_H_
//	定义一个模板类用于模拟ArrayList集合的操作(java)
template<class T>
class ArrayList {
private:
	T* datas;	 //	存放的数据
	int realLen; // 真实数据大小
	int captial; // 实际容量
	//	实现数据拷贝的方法
	void copyDatas(T* from, T* to, int len);
	//	检查当前的下标是否越界
	void checkOutOfBand(int index);
	//	进行扩容的操作
	void resize(int size) ;
public:
	ArrayList(int size);
	ArrayList();
	~ArrayList();
	//	获取一个元素的操作
	T get(int index);
	//	添加数据的操作
	void add(T t);
	//	删除数据的操作
	void remove(int index);
	//	获取当前的数据大小
	int size();
	//	打印当前的ArrayList
	void toString();
};




#endif /* TEMPLATE_ARRAYLIST_H_ */

2.ArrayList.cpp的内容

/*
 * ArrayList.cpp
 *
 *  Created on: 2021年5月4日
 *      Author: hy
 *	基于ArrayList.h的实现
 */
#include<iostream>
#include "ArrayList.h"
using namespace std;

class OutOfBoundException: public exception {
public:
	const char* what() const throw () {
		return "数组越界错误!";
	}
};

//	实现数据拷贝的方法
template<class T>
void ArrayList<T>::copyDatas(T* from, T* to, int len) {
	for (int i = 0; i < len; i++) {
		to[i] = from[i];
	}
}

//	检查当前的下标是否越界
template<class T>
void ArrayList<T>::checkOutOfBand(int index) {
	if (index < 0 || index > this->realLen) {
		throw OutOfBoundException();
	}
}

//	构造函数
template<class T>
ArrayList<T>::ArrayList(int size) {
	//	这里可能需要检查当前size是否大于0
	if (size <= 0) {
		throw "当前传入的size小于或者等于0";
	}
	this->realLen = 0;
	this->captial = 10;
	datas = new T[size];
}

template<class T>
ArrayList<T>::ArrayList() {
	this->realLen = 0;
	this->captial = 10;
	datas = new T[captial];
}

template<class T>
ArrayList<T>::~ArrayList() {
	this->realLen = 0;
	delete[] this->datas;
}

//	获取一个元素的操作
template<class T>
T ArrayList<T>::get(int index) {
	//	这里可能需要检查当前的数组越界的问题
	this->checkOutOfBand(index);
	return this->datas[index];
}

//	进行扩容的操作
template<class T>
void ArrayList<T>::resize(int size) {
	// 1. 创建新长度的数组元素
	T* newDatas = new T[size];
	// 2.开始拷贝数据到新数组中
	this->copyDatas(this->datas, newDatas, this->realLen);
	// 3. 释放原来数组内存
	delete[] this->datas;
	// 4. 更新数据操作
	this->captial = size;
	this->datas = newDatas;
}

//	添加数据的操作
template<class T>
void ArrayList<T>::add(T t) {
	int captial = this->captial;
	int realLen = this->realLen;
	if (realLen + 1 > captial) {
		//	开始扩容
		this->resize(captial * 1.5);
	}
	//	最后填充数据
	this->datas[this->realLen++] = t;
}

//	获取当前的数据大小
template<class T>
int ArrayList<T>::size() {
	return this->realLen;
}

//	打印当前的ArrayList
template<class T>
void ArrayList<T>::toString() {
	cout << "ArrayList [ ";
	int len = this->realLen;

	for (int i = 0; i < len; ++i) {
		cout << this->datas[i];
		if (i < len - 1) {
			cout << ",";
		}
	}
	cout << " ]";
	cout << endl;
}

//	删除数据的操作
template<class T>
void ArrayList<T>::remove(int index) {
	this->checkOutOfBand(index);
	//	这里需要将特定删除的数据向前面移动
	for (int i = index; i < this->realLen - 1; i++) {
		this->datas[i] = this->datas[i + 1];
	}
	this->realLen--;
}

3.测试

测试类

/*
 * TemplateFunctionTest.cpp
 *
 *  Created on: 2021年5月4日
 *      Author: hy
 *	当前内容主要为测试和使用当前的模板方法(泛型)
 *	1. 模板方法的创建
 *	2. 模板方法的调用
 */

#include "ArrayList.h"
#include "ArrayList.cpp"

//	定义一个模板方法
template<typename T>
inline T const& Max(T const &a, T const& b) {
	return a > b ? a : b;
}
/*
 //	定义一个数组越界的异常
 class OutOfBoundException: public exception {
 public:
 const char* what() const throw () {
 return "数组越界错误!";
 }
 };

 //	定义一个模板类用于模拟ArrayList集合的操作(java)
 template<class T>
 class ArrayList {
 private:
 T* datas;	 //	存放的数据
 int realLen; // 真实数据大小
 int captial; // 实际容量
 //	实现数据拷贝的方法
 void copyDatas(T* from, T* to, int len) {
 for (int i = 0; i < len; i++) {
 to[i] = from[i];
 }
 }
 //	检查当前的下标是否越界
 void checkOutOfBand(int index) {
 if (index < 0 || index > realLen) {
 throw OutOfBoundException();
 }
 }
 public:
 ArrayList(int size) {
 //	这里可能需要检查当前size是否大于0
 if (size <= 0) {
 throw "当前传入的size小于或者等于0";
 }
 this->realLen = 0;
 this->captial = 10;
 datas = new T[size];
 }
 ArrayList() {
 this->realLen = 0;
 this->captial = 10;
 datas = new T[captial];
 }
 ~ArrayList() {
 this->realLen = 0;
 delete[] this->datas;
 }
 //	获取一个元素的操作
 T get(int index) {
 //	这里可能需要检查当前的数组越界的问题
 this->checkOutOfBand(index);
 return datas[index];
 }
 //	进行扩容的操作
 void resize(int size) {
 // 1. 创建新长度的数组元素
 T* newDatas = new T[size];
 // 2.开始拷贝数据到新数组中
 this->copyDatas(this->datas, newDatas, this->realLen);
 // 3. 释放原来数组内存
 delete[] this->datas;
 // 4. 更新数据操作
 this->captial = size;
 this->datas = newDatas;
 }
 //	添加数据的操作
 void add(T t) {
 int captial = this->captial;
 int realLen = this->realLen;
 if (realLen + 1 > captial) {
 //	开始扩容
 this->resize(captial * 1.5);
 }
 //	最后填充数据
 datas[this->realLen++] = t;
 }
 //	获取当前的数据大小
 int size() {
 return this->realLen;
 }
 //	打印当前的ArrayList
 void toString() {
 cout << "ArrayList [ ";
 int len = this->realLen;

 for (int i = 0; i < len; ++i) {
 cout << this->datas[i];
 if (i < len - 1) {
 cout << ",";
 }
 }
 cout << " ]";
 cout << endl;
 }

 };*/

int main(int argc, char **argv) {
	//	开始调用模板方法
	cout << "当前最大值为:" << Max(1, 2) << endl;
	ArrayList<int> list;
	for (int i = 0; i < 15; i++) {
		list.add((i + 1));
	}
	list.toString();
	cout << "当前集合的长度为:" << list.size() << endl;
	//	删除数据操作
	list.remove(1);
	list.toString();
	cout << "当前集合的长度为:" << list.size() << endl;
	//	通过索引方式获取特定索引下的数据操作
	int index = 18;
	cout << "当前集合中下标为" << index << "的数据为:" << list.get(index) << endl;
	return 0;
}


执行结果
在这里插入图片描述

4.出现的问题

1.有了ArrayList.h,并且在使用的测试类中导入了,却是出现一个错误,说找不到ArrayList<T>::ArrayList()之类的方法,解决办法,直接将ArrayList.cpp也导入进去即可

5.总结

1.C++中创建模板类使用:template<class T>,然后就可以使用ArrayList<T>的方式创建泛型类的实例的操作

2.C++中创建模板类中的进行实现与定义分离的时候(即分开为.h文件和.cpp的时候,需要导入两个才能使用)

3.C++中创建模板方法使用:template<typename T>,如果是模板类的方法需要使用template<class T>,同样可以使用T作为返回值类型

以上是关于C++之模拟ArrayList的操作(模板的使用)的主要内容,如果未能解决你的问题,请参考以下文章

C++之STLmap和set的模拟实现

C++从青铜到王者第十四篇:STL之stack类的初识和模拟实现

Java泛型之类型擦除

C# ArrayList 与 C++ 互操作

C++从青铜到王者第十五篇:STL之queue类的初识和模拟实现

C++的探索路17泛型程序设计与模板之基本形式