C++学习——模板类的使用:自定义数组

使用C++类模板实现自定义数组

案例描述

C++泛型编程的一种主要技术是使用模板(templates)。模板允许程序员编写通用的代码,以处理各种数据类型,而不仅仅是特定的数据类型。通过使用模板,可以实现代码的重用性和灵活性,使得在不同类型上编写相似的代码变得更加容易。

因此,本案例旨在利用类模板实现一个通用的数组,可以对内置数据类型或自定义数据类型进行存储。

案例需求

  • 定义数组类,实现对任意类型数据存储 —— 定义类模板;
  • 将数组中的数据存储到堆区 —— 利用new开辟堆区内存;
  • 构造函数中可以传入数组的容量 —— 数组类中包括成员变量”容量“,且实现输入容量的构造函数;
  • 提供对应的拷贝构造函数以及operator=防止浅拷贝问题 —— 实现拷贝构造函数,重载= 运算符,使用new执行深拷贝
  • 提供尾插法和尾删法对数组中的数据进行增删 —— 实现对应成员函数
  • 可以通过下标的方式访问数组中的元素 —— 重载[] 运算符
  • 可以获取数组中当前元素个数和数组的容量 —— 实现对应成员变量
// 根据上述需求,可以大致确定类模板中的内容

类模板{
	public:
		构造函数
    	拷贝构造函数
        重载operator=
        重载[]
        尾插函数
    	尾删函数
        获得数组容量
        获得元素个数
        析构函数
  	private:
		指针
    	数组容量
    	元素个数          
}

代码实现

对于类模板,由于成员函数在调用阶段才会被创建,因此其无法正常进行分文件编写。于是,我们将数组类MyArray定义在*.hpp*文件中。

MyArray.hpp

#ifndef MYARRAY_HPP_INCLUDED    // 或者使用 #pragma once 保护头文件
#define MYARRAY_HPP_INCLUDED
#include 
using namespace std;
#endif // MYARRAY_HPP_INCLUDED
template <class T>   // 声明模板
class MyArray{
public:
	
    // 构造函数
    MyArray(int capacity){
        this->m_capacity = capacity;
        this->m_size = 0;
        this->mAddress = new T[capacity];  // 在堆区新开辟数组
    }

    // 拷贝构造函数
    MyArray(const MyArray & arr){
        this->m_capacity = arr.m_capacity;
        this->m_size = arr.m_size;
        this->mAddress = new T[this->m_capacity];  // 要先定义
        for (int i=0;i<arr.m_size;i++){
            this->mAddress[i] = arr.mAddress[i];	// 这里需要调用类型T中的赋值操作,如果类型T是自定义类型,要注意在该类中潜在存在的浅拷贝问题
        }
    }

    MyArray& operator =(const MyArray & arr){

        // 先判断原来堆区是否有问题
        if (this->mAdress != nullptr){
            delete[] this->mAddress;  // 使用new[]开辟的,需要用delete[]删除
            this->m_size = 0;
            this->m_capacity = 0;
        }

        // 赋值
        this->m_capacity = arr.m_capacity;
        this->m_size = arr.m_size;

        // 深拷贝
        this->mAddress = new T[this->m_capacity];
        for (int i=0;i<this->m_size;i++){
            this->mAddress[i] = arr.mAddress[i]; 
        }
        // 注意要有返回值
        return *this;  // 解引用,获得this指向的对象,也就是MyArray类的对象
    }

    // 重写 []
    T& operator [](int index){
        return this->mAddress[index];  // 未考虑越界问题
    }

    // 尾插函数
    void m_push_back(const T & val){
        // 首先判断当前数组是否饱和
        if (this->m_size < this->m_capacity){
            this->mAddress[this->m_size] = val;
            this->m_size++;
        }
    }

    // 尾删函数
    void m_pop_back(){
        // 直接修改当前元素个数即可
        if (this->m_size > 0){
            this->m_size--;
        }
    }
    
	// 获得容量
    int getCapacity(){
        return this->m_capacity;
    }

    // 获得元素个数
    int getSize(){
        return this->m_size;
    }

    // 析构函数
    ~MyArray() {
        if (this->mAddress != NULL){
            delete[] this->mAddress;
            this->m_capacity = 0;
            this->m_size = 0;
            this->mAddress = NULL;
        }
    }

private:
    T * mAddress;  // 指向堆区数组的指针
    int m_capacity;  // 数组容量
    int m_size;  // 数组元素个数

};

案例来源&教程参考

黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难_哔哩哔哩_bilibili

你可能感兴趣的:(c++,学习,开发语言)