主函数
//构造函数(容量) 拷贝构造 operator=
//利用下标方式访问数组中元素
//尾插法 尾删法
//获取数组容量 获取数组大小
//析构
#include<iostream>
using namespace std;
#include"MyArray.hpp"
void printIntArray(MyArray<int>& arr) {
for (int i = 0; i < arr.getSize(); i++) {
cout << arr[i] << endl;
}
}
void test01() {
MyArray <int>arr1(5);
for (int i = 0; i < 5; i++) {
//利用尾插法向数组中插入数据
arr1.Push_back(i);
}
cout << "arr1的打印输出为: " << endl;
printIntArray(arr1);
cout << "arr1的容量为: " << arr1.getCapacity() << endl;
cout << "arr1的大小为: " << arr1.getSize() << endl;
MyArray <int>arr2(arr1);
cout << "arr2的打印输出为: " << endl;
printIntArray(arr2);
//尾删
arr2.Pop_Back();
cout << "arr2尾删后: " << endl;
cout << "arr2的容量为: " << arr2.getCapacity() << endl;
cout << "arr2的大小为: " << arr2.getSize() << endl;
//拷贝问题(深拷贝或者operator=)
MyArray <int>arr3(100);
arr3 = arr1;
}
//测试自定义数据类型
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 << " 年龄: " << arr[i].m_Age << endl;
}
}
void test02() {
MyArray<Person>arr(10);
Person p1("孙策", 30);
Person p2("周瑜", 28);
Person p3("孙权", 22);
Person p4("陆逊", 21);
Person p5("吕蒙", 25);
//将数据插入到数组中
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;
}
int main() {
test01();
test02();
}
头文件? .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.pAddrerss; 本句是浅拷贝问题所在,堆区内存重复释放
//深拷贝
this->pAddress = new T[arr.m_Capacity];
//将arr中数据拷贝过来(如果arr内部原来有着数据)
for (int i = 0; i < this->m_Size; i++) {
this->pAddress[i] = arr.pAddress[i];
}
}
//operate= 防止浅拷贝问题
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++; //更新数组大小
}
//尾删法
void Pop_Back() {
//让用户访问不到最后一个元素,即为尾删,逻辑删除
if (this->m_Size == 0) {
return;
}
this->m_Size--;
}
//通过下标方式访问数组中的元素 arr[0]
//arr是自定义数据类型(对象),使用数组元素的[]是无法被编译器识别的
//必须使用运算符重载 operator[]
//如果想使T返回值作为一个引用存在,需要返回T的引用
//左值:即数值可以被更改,且更改影响该数值的最根本值左值
//不加引用是创建一个新的对象
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; //数组大小
};
|