(3)类模板案例:数组类封装

案例描述:实现一个通用数组类

  • 可以对内置数据类型以及自定义数据类型的数据进行存储
  • 将数组中的数据存储到堆区
  • 构造函数中可以传入数组的容量
  • 提供对应的拷贝构造函数以及operator=防止浅拷贝问题
  • 提供尾插法和尾删法对数组中的数据进行增加和删除
  • 可以通过下标的方式访问数组中的元素
  • 可以获取数组中当前元素个数和数组的容量

分析:

MyArray.hpp

//自己的通用数组类
#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 = arr.pAddress; 指针不能这样赋值,浅拷贝会出问题
		//深拷贝
		this->pAddress = new T[arr.m_Capacity];
		//将arr中数据都拷贝过来
		for (int i = 0; i < this->m_Size; i++) {
			//普通类型可以直接= 但指针类型需要深拷贝
			this->pAddress[i] = arr.pAddress[i];
		}
	}
	//重载 操作符 operator= 防止浅拷贝问题
	MyArray& operator=(const MyArray&arr) {
		//cout << "MyArray 的 operator= 调用" << endl;
		//先判断原来堆区是否有数据,如有先释放数据
		if (this->pAddress != NULL) {
			delete[]this->pAddress;
			this->pAddress = NULL;
			this->m_Capacity = 0;
			this->m_Size = 0;
		}
		//深拷贝
		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];
		}
		return *this;
	}
	//尾插法
	void Push_Back(const T& val) {
		//判断容量是否等于大小
		if (this->m_Capacity == this->m_Size) {
			return;
		}
		this->pAddress[this->m_Size] = val;//在数组末尾插入数据
		this->m_Size++;//Size同步更新,更新数组大小
	}
	//尾删法
	void Pop_Back() {
		//让用户访问不到最后一个元素,即为尾删,逻辑删除
		if (this->m_Size == 0) {
			return;
		}
		this->m_Size--;
	}
	//重载[] 通过下标方式访问数组中的元素 arr[0] = 100
	 T& operator[](int index) {
	   return this->pAddress[index];
	}
	 //返回数组容量
	 int getCapacity() {
		 return this->m_Capacity;
	 }
	 //返回数组大小
	 int getSize() {
		 return this->m_Size;
	 }
	//析构函数
	~MyArray() {
		if (this->pAddress != NULL) {
			//cout << "MyArray析构函数调用" << endl;
			delete[]this->pAddress;
			this->pAddress = NULL;
		}
	}
private:
	T* pAddress;//指针指向堆区开辟的真实数组
	int m_Capacity;//数组容量
	int m_Size;//数组大小
};

测试.cpp

#include<iostream>
using namespace std;
#include"MyArray.hpp"
#include<string>
void printIntArray(MyArray<int>&arr) {
	for (int i = 0; i < arr.getSize(); i++) {
		cout << arr[i] << endl;//测中括号索引
	}
}
void test01() {
	MyArray<int>arr1(5);//MyArray有参构造调用
	for (int i = 0; i < 5; i++) {
		//利用尾插法向数组中插入数据
		arr1.Push_Back(i);//测尾插法
	}
	cout << "arr1的打印输出为: " << endl;
	printIntArray(arr1);
	cout << "arr1的容量为: " << arr1.getCapacity() << endl;//5
	cout << "arr1的大小为: " << arr1.getSize() << endl;//5

	MyArray<int>arr2(arr1);//MyArray拷贝构造调用
	cout << "arr2的打印输出为: " << endl;
	printIntArray(arr2);
	//尾删
	arr2.Pop_Back();
	cout << "arr2尾删后:" << endl;
	cout << "arr2的容量为: " << arr2.getCapacity() << endl;//5
	cout << "arr2的大小为: " << arr2.getSize() << endl;//4
	
	//MyArray<int>arr3(100);//MyArray有参构造调用
	//arr3 = arr1;//MyArray 的 operator= 调用
	//MyArray析构函数调用
	//MyArray析构函数调用
	//MyArray析构函数调用
}
//测试自定义数据类型
class Person {
public:
	Person() {};
	Person(string name, int age) {
		this->m_Name = name;
		this->m_Age = age;
	}
	string m_Name;
	int m_Age;
};
void printPersonArray(MyArray<Person>& arr) {
	for (int i = 0; i < arr.getSize(); i++) {
		cout << "姓名:" << arr[i].m_Name << "\t年龄:" << arr[i].m_Age << endl;
	}
}
void test02() {
	MyArray<Person> arr(10);
	Person p1("一一一",55);
	Person p2("尔尔", 42);
	Person p3("思思", 34);
	Person p4("娃娃", 25);
	Person p5("丽丽", 8);
	//将数据插入到数组中
	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;//10
	cout << "arr大小为: " << arr.getSize() << endl;//5
}
int main() {
	test01();
	test02();
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值