类模板案例
- 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的使用时机;