类模板案例,含金量较高,建议反复练习,吃透知识点

本文介绍了如何使用C++模板实现一个通用的动态数组类,包括构造函数、拷贝构造函数和赋值运算符的实现以避免浅拷贝问题。此外,还提供了尾插法和尾删法来增加和删除元素,以及通过下标访问数组元素的方法。并通过实例展示了如何使用该数组类存储内置类型和自定义数据类型,如存储和操作整型数组和自定义的person类对象数组。
摘要由CSDN通过智能技术生成

目录

类模板案例

第一步

 第二步

测试自定义数据类型


类模板案例

案例描述: 实现一个通用的数组类,要求如下:

  • 可以对内置数据类型以及自定义数据类型的数据进行存储(设计一个类,私有设置属性,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();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值