14.2.9重学C++之【案例:类模板实现自定义通用数组】

MyArray.hpp

#pragma once
#include<iostream>
#include<string>
using namespace std;


template<class T>
class MyArray
{
public:
    // 有参构造
    MyArray(int capacity)
    {
        cout << "MyArray的有参构造" << endl;
        this->arr_capacity = capacity;
        this->arr_size = 0;
        this->arr_paddr = new T[this->arr_capacity];
    }


    // 拷贝构造
    MyArray(const MyArray & arr)
    {
        cout << "MyArray的拷贝构造" << endl;
        /*
        //默认浅拷贝如下:
        this->arr_capacity = arr.arr_capacity;
        this->arr_size = arr.arr_size;
        this->arr_paddr = arr.arr_paddr; // 会出问题
        */

        //手动深拷贝
        this->arr_capacity = arr.arr_capacity;
        this->arr_size = arr.arr_size;
        this->arr_paddr = new T[arr.arr_capacity];

        for(int i=0; i<this->arr_size; i++)
        {
            this->arr_paddr[i] = arr.arr_paddr[i]; // 将arr中原有数据都拷贝过来
        }
    }


    // 重载=,也是为了防止浅拷贝问题
    MyArray& operator=(const MyArray& arr)
    {
        cout << "MyArray的operator=" << endl;
        //先判断原来堆区是否有数据,有的话需要先释放
        if(this->arr_paddr != NULL)
        {
            delete[] this->arr_paddr;
            this->arr_paddr = NULL;
            this->arr_capacity = 0;
            this->arr_size = 0;
        }

        //深拷贝
        this->arr_capacity = arr.arr_capacity;
        this->arr_size = arr.arr_size;
        this->arr_paddr = new T[arr.arr_capacity];

        for(int i=0; i<this->arr_size; i++)
        {
            this->arr_paddr[i] = arr.arr_paddr[i];
        }

        return *this; // 返回自身
    }


    // 尾插法
    void back_push(const T & val)
    {
        //判断容量是否等于大小
        if(this->arr_capacity == this->arr_size)
        {
            return;
        }
        this->arr_paddr[this->arr_size] = val; // 数组末尾插入数据
        this->arr_size++;
    }


    // 尾删法
    void back_pop()
    {
        //逻辑删除,令用户访问不到最后一个元素
        if(this->arr_size == 0)
        {
            return;
        }
        this->arr_size--;
    }


    // 重载[],通过下标方式访问数组元素
    T& operator[](int index)
    {
        return this->arr_paddr[index];
    }


    int get_capacity()
    {
        return this->arr_capacity;
    }


    int get_size()
    {
        return this->arr_size;
    }


    // 析构
    ~MyArray()
    {
        cout << "MyArray的析构函数" << endl;
        if(this->arr_paddr != NULL)
        {
            delete[] this->arr_paddr;
            this->arr_paddr = NULL;
        }
    }


private:
    T * arr_paddr; // 指针指向堆区开辟的真实数组
    int arr_capacity; // 数组容量
    int arr_size; // 数组元素个数
};

main.cpp

#include<iostream>
#include<stdlib.h>
#include<string>
using namespace std;
#include "MyArray.hpp"


/*
    1.3.9类模板案例
        案例描述:
            实现一个通用的数组类,
        要求如下:
            可以对内置数据类型以及自定义数据类型的数据进行存储
            将数组中的数据存储到堆区
            构造函数中可以传入数组的容量
            提供对应的拷贝构造函数以及operator=防止浅拷贝问题
            提供尾插法和尾删法对数组中的数据进行增加和删除
            可以通过下标的方式访问数组中的元素
            可以获取数组中当前元素个数和数组的容量
*/


void test(){
    MyArray <int>arr1(5);
    cout << endl;
    MyArray <int>arr2(arr1);
    cout << endl;
    MyArray <int>arr3(100);
    arr3 = arr1;
    cout << endl;
}


void print_arr(MyArray <int> & arr)
{
    for(int i=0; i<arr.get_size(); i++)
    {
        cout << arr[i] << endl;
    }
}


void test2(){
    MyArray <int> arr1(5);
    for(int i=0; i<5; i++)
    {
        arr1.back_push(i); // 尾插法向数组插入数据
    }
    print_arr(arr1);
    cout << "数组的容量:" << arr1.get_capacity() << endl;
    cout << "数组的大小:" << arr1.get_size() << endl;


    MyArray <int>arr2(arr1);
    print_arr(arr2);
    arr2.back_pop(); // 尾删arr2最后一个元素
    cout << "数组的容量:" << arr2.get_capacity() << endl;
    cout << "数组的大小:" << arr2.get_size() << endl;
}


// 自定义数据类型
class Person
{
public:
    string name;
    int age;

    Person(){} // 空实现无参构造
    Person(string _name, int _age) // 有参构造
    {
        this->name = _name;
        this->age = _age;
    }
};


void print_personarr(MyArray <Person> & arr)
{
    for(int i=0; i<arr.get_size(); i++)
    {
        cout << "name:" << arr[i].name << " age:" << arr[i].age << endl;
    }
}


void test3(){
    MyArray <Person> arr(10);
    Person p1("lanlingwang", 25);
    Person p2("zhenji", 22);
    Person p3("milaidi", 29);
    Person p4("guanyu", 45);

    arr.back_push(p1);
    arr.back_push(p2);
    arr.back_push(p3);
    arr.back_push(p4);
    print_personarr(arr);
    cout << "数组的容量:" << arr.get_capacity() << endl;
    cout << "数组的大小:" << arr.get_size() << endl;

}


int main(){
    //test();
    //test2();
    test3();

    system("pause");
    return 0;
}

test1

test2

test3

 

posted @   yub4by  阅读(132)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示