前面学了那么多东西,现在我们来一个案例,为什么要专门拿出来讲呢?
因为我到时候准备专门出一期关于这个题目的视频,倒不是因为这个题难,主要是涉及的东西多,一些细节也比较多,下面是关于类的要求。
#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; } } };
测试的部分就交给大家自己写了,可以期待一下我接下来出的关于这一篇博客的视频,嘿嘿嘿,当然,自己能理解更好。