目录
类模板案例
案例描述: 实现一个通用的数组类,要求如下:
-
可以对内置数据类型以及自定义数据类型的数据进行存储(设计一个类,私有设置属性,public:提供接口,然后把数据new到堆区)
-
将数组中的数据存储到堆区(使用this指针,把数据导向堆区)
-
构造函数中可以传入数组的容量
-
提供对应的拷贝构造函数以及operator=防止浅拷贝问题(写好拷贝构造,析构,防止浅拷贝带来的问题)
-
提供尾插法和尾删法对数组中的数据进行增加和删除(使用下标的方式来访问)
-
可以通过下标的方式访问数组中的元素
-
可以获取数组中当前元素个数和数组的容量
第一步
写一个自己的通用数组类
创建一个my_array.hpp的文件
可以对内置数据类型以及自定义数据类型的数据进行存储(设计一个类,私有设置属性,public:提供接口,然后把数据new到堆区)
将数组中的数据存储到堆区(使用this指针,把数据导向堆区)
构造函数中可以传入数组的容量
提供对应的拷贝构造函数以及operator=防止浅拷贝问题(写好拷贝构造,析构,防止浅拷贝带来的问题)
#pragma once
#include<iostream>
#include<string>
using namespace std;
template<class T>
class my_array
{
public:
//有参构造
my_array(int capacity)
{
cout << "my_array调用" << endl;
this->m_capa_city = capacity;//给数组容量提供接口,方便外部访问
this->m_size = 0;//初始化,数组容量,使其等于零
this->p_address = new T[this->m_capa_city];//把数据导入堆区
}
//拷贝构造
my_array(const my_array& arr)
{
this->m_capa_city = arr.m_capa_city;
this->m_size = arr.m_size;
//this->p_address = arr.p_address; 因为这是浅拷贝,会导致堆区数据重复释放
//解决该问题,需要重新开辟空间,释放数据
//根据传进来的数据大小开辟空间
this->p_address = new T[arr.m_capa_city];//这个就是深拷贝
//将arr中的数据都拷贝过来
for (int i = 0; i < this->m_size; i++)
{
this->p_address[i] = arr.p_address[i];
}
}
//operator = 也是防止拷贝问题 a=b=c,党b是void类型,就不能给c了,因此要重载=
my_array& operator=(const my_array& arr)
{
//先判断原来数组有无数据,如果有的话先释放
if (this->p_address != NULL)
{
delete[]this->p_address;
this->p_address = NULL;
this->m_capa_city = 0;
this->m_size = 0;
}
//深拷贝
this->m_capa_city = arr.m_capa_city;
this->m_size = arr.m_size;
this->p_address= new T[arr.m_capa_city];
//把所有数据拷贝过来
for (int i = 0; i < this->m_size; i++)
{
this->p_address[i] = arr.p_address[i];
}
return *this;
}
~my_array()//提供析构函数,把堆区数据释放
{
if (this->p_address != NULL)//判断数组是否为空
{
delete[]this->p_address;//把数据删除
this->p_address = NULL;//指向空,是防止它成为野指针
}
}
private :
T* p_address; //指针指向堆区开辟的真实数组
int m_capa_city;//数组容量
int m_size;//数组的大小
};
然后再源文件调用测试
#include"my_array.hpp"
void test01()
{
my_array <int>arr1(5);//因为操作的是模板数据,所要加上<int>模板数据类型
my_array<int>arr2(arr1);//测试拷贝函数
}
为了标注运行成功,在.hpp文件中构造函数和析构函数上加上
cout打印标识
第二步
提供尾插法和尾删法对数组中的数据进行增加和删除(使用下标的方式来访问)
在.hpp文件中提供尾插和尾删法
//尾插法
void push_back(const T& val)//这里插入T 类型的数据,const防止修改,
{
//先判断容量是否等于零
if (this->m_capa_city == this->m_size)
{
cout << "数组已满,禁止插入" << endl;
return;
}
this->p_address[this->m_size] = val;//这样久就查到了尾巴后边
this->m_size++;//更新数组大小
}
//尾删法 让用户访问不到最后一个尾数,即为尾删,逻辑删除
void pop_back()
{
if (this->m_size == 0)//先判断容量是否等于零
{
return;
}
this->m_size--;
}
为了使数组可以重复打印不同的数据,首先要对[]重载,并使其变成可以操作的左值。
//通过下标的方式访问元素,和正常下标访问是一样的,
//但是不一样的是,要面临各种各样的数据传入,所以要使用operator先重载一下
T &operator[](int index)
{
return this->p_address[index];
}
//返回数组的容量
int get_capa_city()
{
return this->m_capa_city;
}
//返回数组的大小
int get_size()
{
return this->m_size;
}
在.cpp文件中调用
现将之前的注释掉
void print_int_array(my_array<int>&arr)
{
for (int i = 0; i < arr.get_size(); i++)
{
cout << arr[i] << endl;
}
}
void test01()
{
my_array <int>arr1(5);//因为操作的是模板数据,所要加上<int>模板数据类型
//my_array<int>arr2(arr1);//测试拷贝函数
//my_array<int>arr3(100);
//arr3 = arr1;
//测试尾插法
for (int i = 0; i < 5; i++)
{
//利用尾插法向数组中插入数据
arr1.push_back(i);
}
cout << "arr1的打印输出为:" << endl;//放到一个函数中去打印输出
print_int_array(arr1);
}
然后看一下arr1的容量和大小
然后在打印一个arr2的
void print_int_array(my_array<int>&arr)
{
for (int i = 0; i < arr.get_size(); i++)
{
cout << arr[i] << endl;
}
}
void test01()
{
my_array <int>arr1(5);//因为操作的是模板数据,所要加上<int>模板数据类型
//my_array<int>arr2(arr1);//测试拷贝函数
//my_array<int>arr3(100);
//arr3 = arr1;
//测试尾插法
for (int i = 0; i < 5; i++)
{
//利用尾插法向数组中插入数据
arr1.push_back(i);
}
cout << "arr1的打印输出为:" << endl;//放到一个函数中去打印输出
cout << "arr1的容量为: " << arr1.get_capa_city() << endl;
cout << "arr1的大小为: " << arr1.get_size() << endl;
print_int_array(arr1);
my_array <int>arr2(arr1);
print_int_array(arr2);
cout << "arr2的容量为: " << arr2.get_capa_city() << endl;
cout << "arr2的大小为: " << arr2.get_size() << endl;
}
测试自定义数据类型
接下来测试自定义数据类型
先创建一个类
class person {
public:
person()
{
}
person(string name, int age)
{
this->m_name = name;
this->m_age = age;
}
public:
string m_name;
int m_age;
};
开始填数据,并使用尾插法,把数据装进去
再循环打印出来
void print_person_array(my_array<person>&person_arr)
{
for (int i = 0; i < person_arr.get_size(); i++)
{
cout << "姓名:" << person_arr[i].m_name << " 年龄" << person_arr[i].m_age << endl;
}
}
void test02()
{
my_array<person>p_array(10);
person p1("孙悟空", 67);
person p2("赵四", 27);
person p3("赵无", 25);
person p4("赵六", 24);
person p5("赵七", 23);
//将数据插入数组中
p_array.push_back(p1);
p_array.push_back(p2);
p_array.push_back(p3);
p_array.push_back(p4);
p_array.push_back(p5);
//打印函数
print_person_array(p_array);
//输出容量和大小
cout << "自定义数据类型arr的容量为: " << p_array.get_capa_city() << endl;
cout << "自定义数据类型arr的大小为: " << p_array.get_size() << endl;
}
调用test02();