需求描述: 通过使用 C++ 中类模板的特性,实现一个能够存储任意类型的数组。可以通过在尾部追加的方式在数组中完成数据传入,且可以通过尾部操作删除数组最后一个元素。完整代码如下:
#include<iostream>
#include<string>
using namespace std;
template<class T>
class Array {
public:
explicit Array(int capacity) {
this->m_capacity = capacity;
this->m_size = 0;
this->m_address = new T[this->m_capacity];
}
~Array() {
if (this->m_address != nullptr) {
delete[] this->m_address;
this->m_address = nullptr;
}
}
Array(const Array &a) {
this->m_capacity = a.m_capacity;
this->m_size = a.m_size;
this->m_address = new T[a.m_capacity];
for (int i = 0; i < this->m_size; i++) {
this->m_address[i] = a.m_address[i];
}
}
Array &operator=(const Array &a) {
//
if (this->m_address != nullptr) {
delete[] this->m_address;
this->m_address = nullptr;
this->m_capacity = 0;
this->m_size = 0;
}
this->m_capacity = a.m_capacity;
this->m_size = a.m_size;
this->m_address = new T[a.m_capacity];
for (int i = 0; i < this->m_size; i++) {
this->m_address[i] = a.m_address[i];
}
return *this;
}
// 在数组末尾追加元素
void append(const T &var) {
if (this->m_capacity == this->m_size) {
return;
}
this->m_address[this->m_size] = var;
this->m_size++;
}
// 删除数组末尾元素
void pop() {
if (this->m_size == 0) {
return;
}
this->m_size--;
}
// 运算符重载函数,通过下标访问数组中的元素
T &operator[](int index) {
if (index > this->m_size - 1 || index < 0) {
cout << "out of range." << endl;
exit(20);
}
return this->m_address[index];
}
int get_capacity() {
return this->m_capacity;
}
int get_size() {
return this->m_size;
}
private:
int m_capacity{};
int m_size{};
T *m_address; // 堆区
};
class Demo {
public:
Demo() = default; // 使用系统默认构造函数,此无参构造函数不可省略,也可以使用自定义无参构造函数
Demo(int id, string name) : m_id(id), m_name(name) {}
int get_id() const {
return this->m_id;
}
string get_name() const {
return this->m_name;
}
private:
int m_id;
string m_name;
};
int main() {
int capacity = 10;
int length = 5;
Array<int> array(capacity);
for (int i = 0; i < length; i++) {
array.append(i);
}
cout<<"通过末尾追加的方式插入数据,此时数组内的数据如下:"<<endl;
for (int i = 0; i < array.get_size(); i++) {
cout << "数组中的第" << i + 1 << "个元素的值为:" << array[i] << endl;
}
cout << "数组的容量为:" << array.get_capacity() << endl;
cout << "数组的长度为:" << array.get_size() << endl;
array.pop();
cout << "Pop一次后数组的容量为:" << array.get_capacity() << endl;
cout << "Pop一次后数组的长度为:" << array.get_size() << endl;
cout<<"Pop 一次后,此时数组内的数据如下:"<<endl;
for (int i = 0; i < array.get_size(); i++) {
cout << "数组中的第" << i + 1 << "个元素的值为:" << array[i] << endl;
}
Array<int> c_array(array);
cout << "使用拷贝构造函数创建对象 demo " << endl;
for (int i = 0; i < c_array.get_size(); i++) {
cout << "demo 数组中的第" << i + 1 << "个元素的值为:" << c_array[i] << endl;
}
cout << "在数组中插入自定义类型:" << endl;
Demo d(1, "赵云");
Demo e(2, "诸葛亮");
Demo f(3, "刘备");
Array<Demo> cus_array(4);
cus_array.append(d);
cus_array.append(f);
cus_array.append(e);
for (int i = 0; i < cus_array.get_size(); i++) {
cout << "自定义类型数组中的第" << i + 1 << "个人的 id 为:" << cus_array[i].get_id() << "\t姓名为:" << cus_array[i].get_name()
<< endl;
}
return 0;
}
运行结果:
通过末尾追加的方式插入数据,此时数组内的数据如下:
数组中的第1个元素的值为:0
数组中的第2个元素的值为:1
数组中的第3个元素的值为:2
数组中的第4个元素的值为:3
数组中的第5个元素的值为:4
数组的容量为:10
数组的长度为:5
Pop一次后数组的容量为:10
Pop一次后数组的长度为:4
Pop 一次后,此时数组内的数据如下:
数组中的第1个元素的值为:0
数组中的第2个元素的值为:1
数组中的第3个元素的值为:2
数组中的第4个元素的值为:3
使用拷贝构造函数创建对象 demo
demo 数组中的第1个元素的值为:0
demo 数组中的第2个元素的值为:1
demo 数组中的第3个元素的值为:2
demo 数组中的第4个元素的值为:3
在数组中插入自定义类型:
自定义类型数组中的第1个人的 id 为:1 姓名为:赵云
自定义类型数组中的第2个人的 id 为:3 姓名为:刘备
自定义类型数组中的第3个人的 id 为:2 姓名为:诸葛亮
Note: 自定义类型数组中的无参构造函数不能省略,否则出现以下报错。
/cygdrive/h/workspaces/c++/example/main.cpp: In instantiation of 'Array<T>::Array(int) [with T = Demo]':
/cygdrive/h/workspaces/c++/example/main.cpp:135:28: required from here
/cygdrive/h/workspaces/c++/example/main.cpp:12:27: error: no matching function for call to 'Demo::Demo()'
12 | this->m_address = new T[this->m_capacity];
| ^~~~~~~~~~~~~~~~~~~~~~~
/cygdrive/h/workspaces/c++/example/main.cpp:91:5: note: candidate: 'Demo::Demo(int, std::string)'
91 | Demo(int id, string name) : m_id(id), m_name(name) {}
| ^~~~
/cygdrive/h/workspaces/c++/example/main.cpp:91:5: note: candidate expects 2 arguments, 0 provided
/cygdrive/h/workspaces/c++/example/main.cpp:88:7: note: candidate: 'Demo::Demo(const Demo&)'
88 | class Demo {
| ^~~~
/cygdrive/h/workspaces/c++/example/main.cpp:88:7: note: candidate expects 1 argument, 0 provided
/cygdrive/h/workspaces/c++/example/main.cpp:88:7: note: candidate: 'Demo::Demo(Demo&&)'
/cygdrive/h/workspaces/c++/example/main.cpp:88:7: note: candidate expects 1 argument, 0 provided
make[3]: *** [CMakeFiles/example.dir/build.make:76: CMakeFiles/example.dir/main.cpp.o] Error 1
make[2]: *** [CMakeFiles/Makefile2:83: CMakeFiles/example.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:90: CMakeFiles/example.dir/rule] Error 2
make: *** [Makefile:124: example] Error 2