16.2.9类模板案例-通用数组

  • Post author:
  • Post category:其他




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 版权协议,转载请附上原文出处链接和本声明。