C++之模拟ArrayList的操作(模板的使用)
Posted 你是小KS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++之模拟ArrayList的操作(模板的使用)相关的知识,希望对你有一定的参考价值。
1.声明
当前内容主要为本人学习C++的操作,主要为模拟Java中的ArrayList的基本操作
主要有
- 实现添加数据
- 删除数据
- 自动扩容为原来的1.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++从青铜到王者第十四篇:STL之stack类的初识和模拟实现