C++ class template case-array encapsulation

C++ Class Template Case-Array Encapsulation

Recently, I took time to watch C++ videos and books. Today I just finished learning this part of the class template, just to summarize and analyze the case in a video. Don't talk nonsense, just start.

The program requirements are as follows:
1. Data of built-in data types and custom data types can be stored.
2. Store the data in the array to the heap area.
3. The capacity of the array can be passed into the constructor.
4. Provide the corresponding copy constructor and operator= to prevent shallow copy problems.
5. Provide tail interpolation and tail deletion methods to add and delete data in the array.
6. The elements in the array can be accessed by subscripting.
7. You can get the current number of elements in the array and the capacity of the array.

1. The overall program design is analyzed.
Insert picture description here
2. The program is realized.
1. First, write the program into files.
Add the header file to write the statement.
Insert picture description here
Because the member functions of the class template are written in files, the creation time of the member functions in the class template is in the calling phase, which leads to file division. The link is not available when writing, so here to solve this problem, write the declaration and implementation in the same file, and change the suffix to **.hpp** (hpp is a convention name, not mandatory)

2. Write your own general array class in MyArray
(1) First write a standard program to introduce

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

(2) Write a few private properties that need to be maintained in the MyArray class

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

int m_Capacity;//数组容量

int m_Size;//数组大小

}

(3) Next, you need to write some external member functions

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) Add and delete data in the array through tail interpolation and tail deletion
(code is as follows:)

//尾插法
	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) Access the elements in the array by subscripting

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

(6) Return array capacity and array size

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

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

(7) Write a test print function, and print the capacity and size of 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) Use arr2 measurement tail method

MyArray<int>arr2(arr1);

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

printIntArray(arr2);

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

}

(9) The test result is as shown in the figure below
Insert picture description here
(10) Finally, the test of the custom data type The
test function is as follows:

//测试自定义数据类型
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;
}

The test results are shown in the figure: The
Insert picture description here
above is the case of the class template I summarized. This case feels very good. The parameter overloading, deep copy and shallow copy are all worth learning. First, I will write a general case of the class template. Column, I have time to write down other basic knowledge of the remembered template in the past two weeks, come on!

Guess you like

Origin blog.csdn.net/qq_45252077/article/details/107858480