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;
}