C++ 类模板案例--数组封装

C++ 类模板案例–数组封装

最近这段时间,抽时间一直在看c++的视频和书籍。今天正好把类模板的这部分给学完了,正好总结总结,分析一个视频里的案例吧。废话不多说,直接开始。

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

一、总体对程序设计进行分析
在这里插入图片描述
二、程序实现
1、先将程序分文件编写
添加头文件以写声明
在这里插入图片描述
因为是类模板成员函数分文件编写,类模板中成员函数创建时机在调用阶段,导致分文件编写时链接不到,所以在这里为解决这个问题,将声明和实现写到同一文件中,并更改后缀名为**.hpp**(hpp是约定名称,并不是强制)

2、在MyArray中写自己通用的数组类
(1)先写标准的程序引入

//自己通用的数组类
#pragma once//防止头文件重复包含
#include<iostream>//标准的io流,头文件引入
using namespace std;//使用标准命名空间

(2)写一下MyArray这个类中需要维护的几个私有属性

template<class T>//因为T不识别,故加类模板T
class MyArray
{
    
    
	
private:
T*pAddress;//指针指向堆区开辟的真实数组

int m_Capacity;//数组容量

int m_Size;//数组大小

}

(3)接下来需要写对外的一些成员函数

public:
	//有参构造,写参数和容量
	MyArray(int capacity)
	{
    
    
		this->m_Capacity=capacity;//通过参数传入容量
		this->m_Size=0;//初始化赋值为0
		this->pAddress=new T[this->m_Capacity];//在堆区创建数据	
	}

	//防止浅拷贝提供拷贝构造函数
	MyArray(const MyArray& arr)
	{
    
    
	//编译器提供
		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)
	{
    
    
	//先判断原来堆区是否有数据,如果有先释放
		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;//最后需要将参数返回
	}



	//因为堆区创建数据,是手动开辟,手动释放故需要写一个析构函数
	//析构函数
	~MyArray()
	{
    
    
		if(this->pAddress!=NULL)
		{
    
    
			delete[]this->pAddress;
		}
	}

(4)通过尾插法和尾删法对数组中的数据进行增加和删除
(代码如下:)

//尾插法
	void Push_Back(const T & vai)
	{
    
    
	//判断容量是否等于大小,若满了的话无法插入,直接返回
		if(this->m_Capacity==this->m_Size)
		{
    
    
		return;
		}
		this->pAddress[this->m_Size]=vai;//在数组末尾插入数据
		this->m_Size++;//更新数组大小
	}

	//尾删法
	void Pop_Back()
	{
    
    
	//让用户访问不到最后一个元素,即为尾删,逻辑删除
		if(this->m_Size==0)
		{
    
    
		return;
		}
		this->m_Size--;
	}

(5)通过下标方式访问数组中的元素

	T& operator[](int index)
	{
    
    
		return this->pAddress[index];
	}

(6)返回数组容量与数组大小

	//返回数组容量
	int getCapacity()
	{
    
    
		return this->m_Capacity;
	}

	//返回数组大小
	int getSize()
	{
    
    
		return this->m_Size;
	}

(7)写测试打印函数,并打印arr1的容量与大小

//写一个打印函数
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<<"arr的打印输出为:"<<endl;

printIntArray(arr1);

//测试一下arr的容量以及大小
cout<<"arr1的容量为:"<<arr1.getCapacity()<<endl;
cout<<"arr1的大小为:"<<arr1.getSize()<<endl;
}

(8)利用arr2测尾删法

MyArray<int>arr2(arr1);

cout<<"arr2的打印输出为:"<<endl;

printIntArray(arr2);

//尾删
arr2.Pop_Back();
cout<<"arr2的容量为:"<<arr2.getCapacity()<<endl;
cout<<"arr2的大小为:"<<arr2.getSize()<<endl;

}

(9)测试结果如下图
在这里插入图片描述
(10)最后为自定义数据类型的测试
测试函数如下:

//测试自定义数据类型
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("wjx",20);
	Person p2("p",20);
	Person p3("hh",908);
	Person p4("aa",308);
	Person p5("999",999);

	//将数据插入到数组中

	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;
}

测试结果如图所示:
在这里插入图片描述
以上就是我总结的有关类模板的案例,这个案例觉得非常不错,里面的参数重载,深拷贝浅拷贝等都非常值得学习一下,先总的写一下类模板的案列,接下来有时间把这两星期记得类模板的其他基本知识给写一写,加油!

猜你喜欢

转载自blog.csdn.net/qq_45252077/article/details/107858480