案例描述: 实现一个通用的数组类,要求如下:
- 可以对内置数据类型以及自定义数据类型的数据进行存储
- 将数组中的数据存储到堆区
- 构造函数中可以传入数组的容量
- 提供对应的拷贝构造函数以及operator=防止浅拷贝问题
- 提供尾插法和尾删法对数组中的数据进行增加和删除
- 可以通过下标的方式访问数组中的元素
- 可以获取数组中当前元素个数和数组的容量
小总结:“拷贝构造” 和 "=赋值操作 " 如果遇到有在堆区开辟的数据,都会有浅拷贝的问题,要写成深拷贝避免重复释放内存。 具体写法见以下代码:
1、第一版测试代码:
myarray.hpp: 包含类模板的头文件写法
#ifndef _MYARRAY_HPP_
#define _MYARRAY_HPP_
#include<iostream>
#include<string>
using namespace std;
template<class T>
class MyArray
{
public:
MyArray(int Capacity)
{
cout << "有参构造函数调用" << endl;
this->m_Capacity = Capacity;
this->m_Size = 0;
this->pAddress = new T[this->m_Capacity];
}
MyArray(const MyArray& arr)
{
cout << "拷贝构造函数调用" << endl;
this->m_Capacity = arr.m_Capacity;
this->m_Size = arr.m_Size;
this->pAddress = new T[this->m_Capacity];
for (int i = 0; i < m_Size; i++)
{
this->pAddress[i] = arr.pAddress[i];
}
}
MyArray& operator=(const MyArray& myarray)
{
cout << "=赋值函数调用" << endl;
if (this->pAddress != NULL)
{
delete[] this->pAddress;
this->m_Capacity = 0;
this->m_Size = 0;
}
this->m_Capacity = myarray.m_Capacity;
this->m_Size = myarray.m_Size;
this->pAddress = new T[this->m_Capacity];
for (int i = 0; i < this->m_Size; i++)
{
this->pAddress[i] = myarray.pAddress[i];
}
return *this;
}
int getCapacity()
{
return this->m_Capacity;
}
int getSize()
{
return this->m_Size;
}
~MyArray()
{
cout << "析构函数调用" << endl;
if (pAddress != NULL)
{
delete[] pAddress;
pAddress = NULL;
this->m_Capacity = 0;
this->m_Size = 0;
}
}
public:
T* pAddress;
int m_Capacity;
int m_Size;
};
#endif
主cpp:
#include<iostream>
#include<string>
#include"myarray.hpp"
using namespace std;
int main()
{
MyArray<int> arr1(10);
MyArray<int> arr2(arr1);
MyArray<int> arr3(10);
arr3 = arr1;
return 0;
}
现象:
2、第二版实现功能代码:
myarray.hpp :
#ifndef _MYARRAY_HPP_
#define _MYARRAY_HPP_
#include<iostream>
#include<string>
using namespace std;
template<class T>
class MyArray
{
public:
MyArray(int Capacity)
{
this->m_Capacity = Capacity;
this->m_Size = 0;
this->pAddress = new T[this->m_Capacity];
}
MyArray(const MyArray& arr)
{
if (this->pAddress != NULL)
{
delete[] this->pAddress;
this->m_Capacity = 0;
this->m_Size = 0;
}
this->m_Capacity = arr.m_Capacity;
this->m_Size = arr.m_Size;
this->pAddress = new T[this->m_Capacity];
for (int i = 0; i < m_Size; i++)
{
this->pAddress[i] = arr.pAddress[i];
}
}
MyArray& operator=(const MyArray& myarray)
{
if (this->pAddress != NULL)
{
delete[] this->pAddress;
this->m_Capacity = 0;
this->m_Size = 0;
}
this->m_Capacity = myarray.m_Capacity;
this->m_Size = myarray.m_Size;
this->pAddress = new T[this->m_Capacity];
for (int i = 0; i < this->m_Size; i++)
{
this->pAddress[i] = myarray.pAddress[i];
}
return *this;
}
T& operator[](int index)
{
return this->pAddress[index];
}
void Push_back(T& data)
{
if (this->m_Capacity == this->m_Size)
{
cout << "数组没有空间了" << endl;
return;
}
this->pAddress[this->m_Size] = data;
this->m_Size++;
}
void Pop_back()
{
if (this->m_Size == 0)
{
cout << "数组中已没有数据,无法删除" << endl;
return;
}
this->m_Size--;
}
int getCapacity()
{
return this->m_Capacity;
}
int getSize()
{
return this->m_Size;
}
~MyArray()
{
if (pAddress != NULL)
{
delete[] pAddress;
pAddress = NULL;
this->m_Capacity = 0;
this->m_Size = 0;
}
}
private:
T* pAddress;
int m_Capacity;
int m_Size;
};
#endif
主cpp :
#include<iostream>
#include<string>
#include"myarray.hpp"
using namespace std;
void PrintInt(MyArray<int>& array)
{
for (int i = 0; i < array.getSize(); i++)
{
cout << array[i] << " ";
}
cout << endl;
}
void test01()
{
MyArray<int> arr1(10);
cout << arr1.getCapacity() << endl;
cout << arr1.getSize() << endl;
MyArray<int> arr2(arr1);
cout << arr2.getCapacity() << endl;
cout << arr2.getSize() << endl;
MyArray<int> arr3(10);
arr3 = arr1;
}
void test02()
{
MyArray<int> arr(10);
for (int i = 0; i < 10; i++)
{
arr.Push_back(i);
}
arr[0] = 100;
arr.Pop_back();
PrintInt(arr);
cout << "----------------------------" << endl;
MyArray<int> arr2(arr);
arr2.Pop_back();
cout << "数组容量:" << arr2.getCapacity() << " " << "数组大小:" << arr2.getSize() << endl;
PrintInt(arr2);
}
class Person
{
public:
Person()
{
}
Person(string name, int age)
{
m_name = name;
m_age = age;
}
~Person()
{
}
public:
string m_name;
int m_age;
};
void PrintPerson(MyArray<Person>& p)
{
for (int i = 0; i < p.getSize(); i++)
{
cout << p[i].m_name<<" "<<p[i].m_age << endl;
}
}
void test03()
{
MyArray<Person> parray(10);
Person p1("张三", 20);
Person p2("李四", 21);
Person p3("王五", 22);
Person p4("赵六", 23);
parray.Push_back(p1);
parray.Push_back(p2);
cout << "容量:" << parray.getCapacity() << " " << "大小:" << parray.getSize() << endl;
PrintPerson(parray);
}
int main()
{
test01();
test02();
test03();
return 0;
}
总结: 这个案例综合性还是比较强的,通过做这个案例,把之前的运算符重载,拷贝构造,类模板知识都复习了一遍,这个案例以后还是经常多敲几遍比较好,巩固一下
|