C++初学:动态数组类模板

动态数组类模板:

  • 任意位置增加任意个数元素
  • 给定位置返回该位置元素
  • 删除任意位置以后任意个元素
  • 数组重新赋值

编程过程中用到了模板类、函数模板、运算符重载、构造函数、析构函数、动态内存分配等知识。理论上改模板能实现存取任意类型(包括自定义)元素。

头文件1:stdafx.h
#ifndef STDAFX_H_INCLUDED
#define STDAFX_H_INCLUDED

#include <iostream>
#include <cmath>

using namespace std;

#endif // STDAFX_H_INCLUDED
头文件2:动态数组类模板 arrs.h
#ifndef ARRS_H_INCLUDED
#define ARRS_H_INCLUDED
#include "stdafx.h"

template<class T>
class arrs {

public:

	//构造函数、拷贝构造函数
	arrs() :nums(0), ptr(nullptr), capacity(7) {}
	arrs(int num) :nums(num > 0 ? num : 1), ptr(num < capacity ? new T[capacity] : new T[num]) {}
	arrs(const arrs& arr) {
		nums = arr.nums;
		ptr = new T[arr.nums];
		for (int i = 0; i < nums; i++) {
			ptr[i] = arr.ptr[i];
		}
	}
	//析构函数
	~arrs() {
		if (ptr) {
			delete[] ptr;
			ptr = nullptr;
		}
		nums = 0;
	}
	//数组重写
	arrs restart() {
		cout << "输入初始数组元素个数:";
		int n = 0;
		cin >> n;
		nums = n;
		cout << endl << "输入每个元素(当前为整型),空格隔开:";
		if (n <= capacity) {  //若总数小于容量,则覆盖原来的数组元素
			for (int i = 0; i < nums; i++) {
				cin >> ptr[i];
			}
			return *this;
		}
		else {
			arrs atemp(n);   //若总数大于容量,则新开辟空间存储
			for (int i = 0; i < n; i++) {
				cin >> atemp.ptr[i];
			}
			return atemp;
		}
	}
	//初始化原始数组
	void input() {
		for (int i = 0; i < nums; i++) {
			cin >> ptr[i];
		}
	}
	//输出当前数组
	void show() {
		cout << endl << "现在的数组:";
		for (int i = 0; i < nums; i++) {
			cout << ptr[i] << "  ";
		}
		cout << endl << endl;
	}
	//获取数组大小
	int getSize() {
		return nums;
	}
	//删除指定位置的元素
	void deleteElem(int n) {
		cout << "输入要删除的元素的位置,空格隔开:";
		int* posptr = new int[n];
		for (int i = 0; i < n; i++) {
			cin >> posptr[i];	//记录要删除的位置
		}
 								//将要删除的位置从小到大排序
		for (int i = 0; i < n - 1; ++i) {
			for (int j = i + 1; j < n; ++j) {   
				if (posptr[i] > posptr[j]) {
					int t = posptr[i];
					posptr[i] = posptr[j];
					posptr[j] = t;
				}
			}
		}

		for (int i = 0; i < n; i++) {  //元素前移
			for (int j = posptr[i]; j < nums; j++) {
				ptr[j - 1] = ptr[j];
			}
			nums--;
			for (int k = 0; k < n; k++) {
				posptr[k] -= 1;   //每删除一个元素,位置同时前移一位
			}
		}
	}
	//获取指定位置的元素
	void getElem() {
		cout << "输入某一元素的位置:";
		int n = 0;
		cin >> n;
		cout << "第" << n << "个元素是:" << ptr[n - 1] << endl;;
	}
	//加号运算符重载
	arrs operator+(int n) {
		cout << "输入要增加的元素,空格隔开:";
		if (nums + n > capacity) {
			arrs atemp(nums + n);   //若总数大于N,则新开辟空间存储
			for (int i = 0; i < nums + n; i++) {
				if (i < nums) { atemp.ptr[i] = ptr[i]; }  //已有元素
				else { cin >> atemp.ptr[i]; }   //追加元素
			}
			return atemp;
		}
		else {
			int t = nums;
			nums += n;  //若总数在N范围之内,则继续追加
			for (int i = t; i < nums; i++) {
				cin >> ptr[i];
			}
			return *this;
		}
	}
	//=运算符重载
	arrs& operator=(arrs& myarray) {

		if (this->ptr != nullptr) {
			delete[] this->ptr;
			this->capacity = 0;
			this->nums = 0;
		}
		this->capacity = myarray.capacity;
		this->nums = myarray.nums;
		this->ptr = new T[this->capacity];
		for (int i = 0; i < this->nums; i++) {
			this->ptr[i] = myarray[i];
		}
		return *this;
	}
	//[]重载
	T& operator[](int index) {
		if (index < 0 || index >= nums) {
			cout << "越界!" << endl;
			return 0;
		}
		return this->ptr[index]; 
	}

	//任意位置增加数组
	arrs expand(int n, int m) {
		cout << "输入要增加的元素,空格隔开:";
		
		if (nums + n > capacity) {
			arrs atemp(nums + n);       //若总数大于N,则新开辟空间存储
			for (int i = 0; i < nums; i++) {
				atemp.ptr[i] = ptr[i];
			}	 						//指定位置后移
			for (int j = m; j < nums; j++) {
				atemp.ptr[j + n] = atemp.ptr[j];
			}
			for (int i = m; i < m + n; i++) {  //指定位置追加元素
				cin >> atemp.ptr[i];
			}
			return atemp;
		}
		else {
			nums += n;    //若总数在N范围之内,则不开辟新数组
			for (int j = m; j < nums; j++) {
				ptr[j + n] = ptr[j];
			}
			for (int i = m; i < m + n; i++) {
				cin >> ptr[i];
			}
			return *this;
		}
	}
public:
	int nums;               //当前数组元素总数
	T* ptr;                 //指向当前数组的指针
	int capacity = 7;       //当前数组最大容量
};


#endif // ARRS_H_INCLUDED
cpp文件:main.cpp
#include "arrs.h"

template<typename DT>
void menu(arrs<DT>& arr1);

int main()
{
	cout << "输入初始数组元素个数:";
	int n = 0;
	cin >> n;
	cout << endl << "输入每个元素(当前为整型),空格隔开:";
	arrs<int> arr1(n);
	//arrs<float> arr1(n); //其他类型
	//arrs<char> arr1(n);
	arr1.input();
	arr1.show();
	menu(arr1);

	system("pause");
	return 0;
}

template<typename DT>
void menu(arrs<DT>& arr1) {
	cout << "------->>>选项: 1.在任意位置扩容数组 2.获取指定位置元素 3.删除指定位置元素 4.数组重新赋值 5.退出" << endl;
	int n = 0;
	cin >> n;
	switch (n) {
	case 1: {
		cout << "分别输入要追加的位置和要增加的元素个数,空格隔开:";
		int n = 0, m = 0;
		cin >> m >> n;
		//arrs<DT> arr2=arr1+n;           //加号运算符重载,只能在最后位置增加元素
		arrs<DT> arr2 = arr1.expand(n, m);//可在任意位置增加元素
		arr2.show();
		menu(arr2); break;
	}
	case 2: {arr1.getElem(); arr1.show(); menu(arr1); break; }
	case 3: {cout << "输入删除个数:"; int n = 0; cin >> n; arr1.deleteElem(n); arr1.show(); menu(arr1); break; }
	case 4: {arrs<DT> arr2 = arr1.restart(); arr2.show(); menu(arr2); break; }
	default:exit(0);
	}
}
运行结果

最终结果

遇到的问题及解决办法

提示:未加载 wntdll.pdb
提示:CRT detected that the application wrote to memory after end of heap buffer
错误提示
原因:内存使用时越界!nums+n是开辟T类型的总个数,引用时却达到了nums+n+n
问题原因
解决办法:将nums+n改为nums即可

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伯明翰谢老二

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值