C++ 开发中,使用类模板完成自定义数组

需求描述: 通过使用 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
上一篇:Forwarding Address字段


下一篇:第63篇-解释器与编译器适配(二)