C++模板(3):类模板案例

本文通过类模板案例详细讲解了如何在C++中使用类模板,涉及堆区对象创建、析构函数、运算符重载、拷贝构造函数的深拷贝以及引用和const的运用。在编写MyArr类模板时,特别强调了防止空指针和正确管理内存的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

类模板案例

在这里插入图片描述

在这里插入图片描述

  • MyArr.hpp:
#pragma once
template<typename T>
class MyArr {
public:
	//有参构造-容量
	MyArr(int capacity) {
		//cout << "myArr有参构造调用" << endl;
		this->m_capacity = capacity;
		this->m_size = 0;
		this->pArrAddress = new T[this->m_capacity];
	}
	//拷贝构造函数--因为为拷贝构造,所以传入的对象指针需要用const锁定
	MyArr(const MyArr& arr) {
		//cout << "拷贝构造函数调用" << endl;
		this->m_capacity = arr.m_capacity;
		this->m_size = arr.m_size;
		//这属于浅拷贝,容易出现问题,因为数组的首地址是不可以进行更改的;
		//this->pAddress = arr.pArrAddress;
		//深拷贝
		this->pArrAddress = new T[this->m_capacity];
		//将arr中的数据拷贝过来
		for (int i = 0; i < arr.m_capacity; i++) {
			this->pArrAddress[i] = arr.pArrAddress[i];
		}
	}
	//MyArr中的operator=运算符重载——防止浅拷贝的问题
	MyArr& operator=(const MyArr& arr) {
		//cout << "operator=函数调用" << endl;
		//因为拷贝涉及数组的容量问题,所以需要重新根据拷贝的对象容量大小进行创建再赋值
		//先判断原来堆区是否有数据,如果有先释放
		if (this->pArrAddress != NULL) {
			delete[] this->pArrAddress;
			this->pArrAddress = NULL;
			this->m_capacity = 0;
			this->m_size = 0;
		}
		this->m_size = arr.m_size;
		this->m_capacity = arr.m_capacity;
		this->pArrAddress = new T[arr.m_capacity];
		for (int i = 0; i < arr.m_capacity; i++) {
			this->pArrAddress[i] = arr.pArrAddress[i];
		}
		return *this;
	}
	//尾删法:
	void Pop_Back() {
		//让用户访问不到即删除,逻辑删除
		if (this->m_size == 0) {
			return;
		}
		this->m_size--;
	}
	//尾插法
	void Push_Back(const T & val) {
		//判断容量是否等于大小
		if (this->m_capacity == this->m_size) {
			return;
		}
		this->pArrAddress[this->m_size] = val;  //在数组末尾插入数据
		this->m_size++;	//更新数组大小
	}
	//返回数组容量
	int getCapacity() {
		return this->m_capacity;
	}
	//返回数组大小
	int getSize() {
		return this->m_size;
	}
	//通过下标方式访问数组中的元素 arr[0]=10
	T& operator[](int index) {
		return this->pArrAddress[index];
	}
	//析构函数
	~MyArr() {
		//cout << "析构函数调用" << endl;
		if (this->pArrAddress != NULL) {
			delete[] this->pArrAddress;	//清空指针指向数组占用的内存
			this->pArrAddress = NULL;
		}
	}
private:
	int m_size; //数组大小
	int m_capacity; //数组容量
	T* pArrAddress; //指针指向堆区开辟的真实数组
};
  • MyArr.cpp
#include<iostream>
using namespace std;
#include<string>
#include"MyArr.hpp"
//测试自定义数据类型
class Person {
public:
	Person() {};
	Person(string name, int age) {
		this->m_Name = name;
		this->m_Age = age;
	}
	string m_Name;
	int m_Age;
};

void printIntArr(MyArr<int>& arr) {
	for (int i = 0; i < arr.getSize(); i++) {
		cout << arr[i] << endl;
	}
}
void printPersonArr(MyArr<Person>& arr) {
	for (int i = 0; i < arr.getSize(); i++) {
		cout << "姓名" << arr[i].m_Age << ";年龄:" << arr[i].m_Name << endl;
	}
}
void test(){
	MyArr<int> arr1(5);
	MyArr<int> arr2(arr1);
	MyArr<int> arr3(6);
	arr3 = arr1;
	arr1.Push_Back(1);
	arr1.Push_Back(2);
	arr1.Pop_Back();
	printIntArr(arr1);
}
void test02() {
	Person p1("张一", 18);
	Person p2("张二", 19);
	Person p3("张三", 20);
	Person p4("张四", 21);
	Person p5("张五", 22);
	MyArr<Person> myarr(5);
	myarr.Push_Back(p1);
	myarr.Push_Back(p2);
	myarr.Push_Back(p3);
	myarr.Push_Back(p4);
	myarr.Push_Back(p5);
	myarr.Pop_Back();
	printPersonArr(myarr);
	
}
int main() {
	//test();
	test02();
	system("pause");
	return 0;
}

注意指针的问题;防止空指针;
同时可复习:
1.类模板的使用
2.堆区的创建,堆区数组的创建;
3.堆区创建对象后,习惯利用析构函数进行手动释放内存;
4.运算符重载;——=、[ ]都可进行重载;
5.拷贝构造函数的使用——深拷贝;(解决浅拷贝容易出错的问题)
6.引用的使用习惯;const的使用时机;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值