前面学了那么多东西,现在我们来一个案例,为什么要专门拿出来讲呢?
因为我到时候准备专门出一期关于这个题目的视频,倒不是因为这个题难,主要是涉及的东西多,一些细节也比较多,下面是关于类的要求。?
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<iostream>
using namespace std;
#include<string>
template<class T>
class MyArray {
private:
T m_Capacity;//数组容量
T m_Size;//数组现有大小
T* pAddress;//数组地址
public:
//构造函数
MyArray(int capacity) {
m_Capacity = capacity;
m_Size = 0;
pAddress = new T[this->m_Capacity];
}
//拷贝构造函数
//arr是一个已存的对象,而this指向的对象才是一个新的,所以需要重新开辟一块堆区空间
MyArray(const MyArray& arr) {
//浅拷贝
this->m_Capacity = arr.m_Capacity;
this->m_Size = arr.m_Size;
//深拷贝
//先让指针指向一块新开辟的堆区空间
this->pAddress = new T[this.m_Capacity];
//关于地址的深拷贝,并没有将地址给新对象,而是选择浅拷贝给到
for (int i = 0; i < arr.m_Size; i++) {
this->pAddress[i] = arr.pAddress[i];
}
}
//重载=运算符,防止浅拷贝问题
MyArray& operator=(const MyArray& myarray) {
//先将对象中的数据彻底删除,然后再放入数据
//因为,=两边的数据类型大小未知,若大小不同,就不能准确的覆盖完全
//可能产生一些未知的后果
if (this->pAddress != NULL) {
delete[] this->pAddress;
this->pAddress = NULL;
this->m_Capacity = 0;
this->m_Size = 0;
}
this->m_Capacity = myarray.m_Capacity;
this->m_Size = myarray.m_Size;
this->pAddress = new T[this->m_Capacity];
for (int i = 0; i < myarray.m_Size; i++) {
this->pAddress[i] = myarray[i];
}
//记得返回本身,即函数返回值返回引用,这样就可以做左值
return *this;
}
//用下标去访问数组元素,重载【】运算符;因为【】前面时对象,不是数组名
T& operator[](int index) {
return this->pAddress[index];
}
//尾插法
void push_back(const T& val) {
if (this->m_Capacity == this->m_Size) {
cout << "满了" << endl;
return;
}
//这里的【】里面只用写this->m_Size,因为数组从零开始存储
//this->m_Size是从零开始加的;
this->pAddress[this->m_Size] = val;
this->m_Size++;
}
//尾删法
//在前面的时候,如果要删除数组中的某个元素,都是选择直接让数组元素前移
//然后再将总体长度减小就行,
//这里就是一种比较特殊的情况了,要删除的元素是最后一个,不需要前移
//任何元素,只需将总长度减一即可;
void pop_back() {
if (this->m_Size == 0) {
return;
}
this->m_Size--;
}
//获取数组容量
int getlong() {
return this->m_Capacity;
}
//获取数组大小
int getsize() {
return this->m_Size;
}
//析构函数
~MyArray() {
if (this->pAddress != NULL) {
delete[] this->pAddress;
this->pAddress = NULL;
this->m_Capacity = 0;
this->m_Size = 0;
}
}
};
测试的部分就交给大家自己写了,可以期待一下我接下来出的关于这一篇博客的视频,嘿嘿嘿,当然,自己能理解更好。
|