16.2.9类模板案例-通用数组
实现一个通用的数组类,要求如下:
- 可以对内置数据类型和自定义数据类型进行存储;
- 将数组中的数据储存到堆区;
- 构造函数中可以传入数组的容量;
- 提供对应的拷贝构造函数以及operator=方式浅拷贝;
- 提供尾插法和尾删法对数组中的数据进行增加和删除;
- 可以通过下标的方式访问数组中的元素;
- 可以获取数组中当前元素的个数和数组的容量。
1、添加新文件myArray.hpp,创建简单的成员函数
这个类其实本质还是系统默认的数组,只是添加了一些功能。
//自己的通用的数组类
#pragma once
#include <string>
#include <iostream>
using namespace std;
template<class T>
class MyArray
{
public:
//有参构造
MyArray(int capacity)
{
this->capacity = capacity;
this->size = 0;
this->pAddress = new T[capacity];
}
//析构
~MyArray()
{
if (this->pAddress != NULL)
{
delete[] this->pAddress;
this->pAddress = NULL;
}
}
private:
T* pAddress; //存放数据的数组
int capacity; //数组容量
int size; //元素个数
};
2、添加拷贝构造函数和operator=防止浅拷贝
拷贝构造函数就是用原数组的容量重新开辟一个空间,并利用for循环将元素一个一个拷贝过来。
//拷贝构造
MyArray(const MyArray& arr)
{
this->pAddress = new T[arr.capacity];
this->capacity = arr.capacity;
this->size = arr.size;
for (int i = 0; i < this->size; i++)
{
this->pAddress[i] = arr.pAddress[i];
}
}
operator=函数要先判断等号左边的对象是否为空,如果不为空,要现释放原对象的指针,再进行拷贝。拷贝过程跟拷贝构造函数相同,最后返回自身的引用。
//operator=
MyArray& operator=(const MyArray& arr)
{
if (this->pAddress != NULL)
{
delete[] this->pAddress;
this->pAddress = NULL;
this->capacity = 0;
this->size = 0;
}
this->capacity = arr.capacity;
this->size = arr.size;
this->pAddress = new T[arr.capacity];
for (int i = 0; i < this->size; i++)
{
this->pAddress[i] = arr.pAddress[i];
}
return *this;
}
3、尾插法和尾删法的实现
加入成员函数尾插法。
尾插法就是再数组的最后加上一个元素,元素个数加一。首先要判断数组容量是否大于元素个数,如果不大于,则无法再进行插入。
//尾插法
void push_Back(const T& value)
{
if (this->capacity == this->size)
{
return;
}
this->pAddress[this->size] = value;
this->size++;
}
//尾删法
void pop_Back()
{
if (this->size == 0)
{
return;
}
this->size--;
}
加入成员函数尾删法。
尾删法就是将最后一个元素删除,并且元素个数减一。同样要先判断还有没有元素了。
4、通过下标的方式访问数组中的元素
重载[]运算符就行了。
//通过下标的方式访问数组中的元素
T& operator[](int index)
{
return this->pAddress[index];
}
5、获取数组容量和大小的成员函数
这里数组大小就是指元素个数。
//返回数组容量
int getCapacity()
{
return this->capacity;
}
//返回数组大小
int getSize()
{
return this->size;
}
6、添加打印函数
用一个成员函数输出数组中的元素,这里仅限<<运算符默认支持的数据类型。
void printArray()
{
for (int i = 0; i < this->size; i++)
{
cout << this->pAddress[i] << ' ';
}
cout << endl;
}
7、用内置数据类型实验
在main.cpp中写入一下代码验证MyArray类的所有功能。
#include <iostream>
#include "myArray.hpp"
#include <string>
using namespace std;
void test1()
{
MyArray<int>arr1(5);
for (int i = 0; i < 5; i++)
{
//测试尾插法
arr1.push_Back(i);
}
cout << "arr1的打印输出为:" << endl;
//测试打印功能
arr1.printArray();
cout << "arr1的容量为:" << arr1.getCapacity() << endl;
cout << "arr1的大小为:" << arr1.getSize() << endl;
//测试拷贝构造函数是否为深拷贝
MyArray<int>arr2(arr1);
cout << "arr2的打印输出为:" << endl;
arr2.printArray();
//测试尾删法
arr2.pop_Back();
//测试获取容量和大小的函数
cout << "arr2的容量为:" << arr2.getCapacity() << endl;
cout << "arr2的大小为:" << arr2.getSize() << endl;
cout << "arr2的打印输出为:" << endl;
arr2.printArray();
}
int main()
{
test1();
}
所有功能都正常。
8、用自定义数据类型实验
简单的测试一下:
//测试自定义数据类型
class Person
{
public:
Person() {}
Person(string name, int age)
{
this->name = name;
this->age = age;
}
string name;
int age;
};
void printPersonArray(MyArray<Person>& arr)
{
for (int i = 0; i < arr.getSize(); i++)
{
cout << "姓名:" << arr[i].name;
cout << "\t年龄:" << arr[i].age << endl;
}
}
void test2()
{
MyArray<Person>arr(10);
Person p1("孙悟空", 999);
Person p2("韩信", 30);
Person p3("妲己", 20);
Person p4("赵云", 22);
Person p5("安其拉", 29);
//将数据插入到数组中
arr.push_Back(p1);
arr.push_Back(p2);
arr.push_Back(p3);
arr.push_Back(p4);
arr.push_Back(p5);
printPersonArray(arr);
cout << "arr的容量为:" << arr.getCapacity() << endl;
cout << "arr的大小为:" << arr.getSize() << endl;
arr.pop_Back();
printPersonArray(arr);
cout << "arr的容量为:" << arr.getCapacity() << endl;
cout << "arr的大小为:" << arr.getSize() << endl;
}
int main()
{
test2();
}
版权声明:本文为qq_32513033原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。