C++ 利用类模板实现一个数组类封装
案例描述:
实现一个通用的数组类,要求如下:
-
可以对内置数据类型以及自定义数据类型的数据进行存储
-
将数组中的数据存储到堆区
-
构造函数中可以传入数组的容量
-
提供对应的拷贝构造函数以及operator=防止浅拷贝问题
-
提供尾插法和尾删法对数组中的数据进行增加和删除
-
可以通过下标的方式访问数组中的元素
-
可以获取数组中当前元素个数和数组的容量
类中的基本方法和对外接口如下:
完整项目请参阅此连接:项目传送门
项目构建说明:
该项目在vscode上开发,在构建项目时请修改.vscode文件中的编译器和调试器路径
项目CMake文件
cmake_minimum_required(VERSION 3.10.0)
project(MyArray VERSION 0.1.0 LANGUAGES C CXX)
file(REMOVE_RECURSE "${PROJECT_BINARY_DIR}/build") # 设置构建目录
include_directories(${PROJECT_SOURCE_DIR}/headers) # 指定头文件目录
aux_source_directory(${PROJECT_SOURCE_DIR}/sources SRC_LIST) # 指定源文件目录
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) # 设置构建生成的二进制文件存储位置
add_executable(main ${SRC_LIST}) # 设置可执行的源文件
include(CTest)
enable_testing()
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
利用类模板实现一个数组类封装
MyArray.hpp
#pragma once
#include<iostream>
using namespace std;
// 模板类
template<class T>
class MyArray{
public:
MyArray(int capacity){
cout << "MyArray有参构造调用" << endl;
this->m_Capacity = capacity;
this->m_Size = 0;
this->pAddress = new T[this->m_Capacity];
}
MyArray(const MyArray& arr){
cout << "MyArray拷贝构造调用" << endl;
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];
}
}
//这里同样防止浅拷贝
MyArray& operator=(const MyArray& arr){
cout << "MyArray赋值拷贝构造调用" << endl;
//这种拷贝方式有可能之前已经有了存储,所以要清除掉之前的数据
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;
}
// 实现基本的尾插法
void Push_Back(const T & val){
if(this->m_Size == this->m_Capacity){
return;
}
this->pAddress[this->m_Size] = val;
this->m_Size++;
}
// 删除尾部数据
void Pop_Back(){
if(this->m_Size == 0){
return;
}
this->m_Size--;
}
T& operator[](int index){
return this->pAddress[index];
}
int Get_Capacity(){
return this->m_Capacity;
}
int Get_Size(){
return this->m_Size;
}
~MyArray(){
if(this->pAddress != NULL){
cout << "MyArray析构调用" << endl;
delete[] this->pAddress;
this->pAddress = NULL;
}
}
private:
T * pAddress;
int m_Capacity;
int m_Size;
};
测试自定义数据类型和内置数据类型
main.cpp
#include<iostream>
#include<string>
using namespace std;
#include "MyArray.hpp"
void printIntArray(MyArray <int>& arr){
for(int i = 0; i< arr.Get_Size(); i++){
cout << arr[i] << endl;
}
}
//测试内置数据类型
void test1(){
MyArray<int>arr1(5);
for(int i = 0; i < 5; i++){
arr1.Push_Back(i);
}
printIntArray(arr1);
cout << "arr1 的容量为:" << arr1.Get_Capacity() << endl;
cout << "arr1 的大小为:" << arr1.Get_Size() << endl;
MyArray<int>arr2(arr1);
printIntArray(arr2);
arr2.Pop_Back();
printIntArray(arr2);
}
// 自定义数据类型
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.Get_Size(); i++){
cout << "姓名:" << arr[i].m_Name << "年龄:" << arr[i].m_Age << endl;
}
}
// 测试自定义数据类型
void test2(){
MyArray<Person>arr(10);
Person p1("孙悟空",999);
Person p2("韩信",30);
Person p3("妲己",20);
Person p4("赵云",25);
Person p5("安琪拉",27);
arr.Push_Back(p1);
arr.Push_Back(p2);
arr.Push_Back(p3);
arr.Push_Back(p4);
arr.Push_Back(p5);
printPersonArray(arr);
}
int main(){
test1();
test2();
}