美文网首页
黑马C++视频笔记《模板:类模板实战案例》

黑马C++视频笔记《模板:类模板实战案例》

作者: 井底蛙蛙呱呱呱 | 来源:发表于2021-01-18 00:26 被阅读0次
/* 案例描述:实现一个通用的数组类,要求如下:
 *  (1)可以对内置数据类型以及自定义数据类型的数据进行储存;
 *  (2)将数组中的数据储存到堆区;
 *  (3)构造函数中可以传入数组的容量;
 *  (4)提供对应的拷贝构造函数以及operator=赋值操作重载防止浅拷贝问题;
 *  (5)提供尾插法和尾删法对数组中的数据进行增加和删除;
 *  (6)可以通过下标的方式访问数组中的元素;
 *  (7)可以获取数组中当前元素个数和数组的容量。
  */

类模板声明及实现

其中,类的声明以及实现均放在一个文件udfArray.hpp中:

//
// Created by shexuan on 2021/1/17.
//

#pragma once

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



template <class T>
class MyArray{
public:
    // 构造函数(传入容量)
    MyArray(int capacity);

    // 拷贝构造
    MyArray(const MyArray<T> & arr);

    // operator= 重载, 防止浅拷贝, 引用方式返回,以便后续可以连续赋值 a=b=c
    MyArray & operator=(const MyArray<T> &arr);

    // 利用下标访问数组的元素
    T& operator[](int index);

    // 尾插法
    void Push_Back(const T& val);

    // 尾删法
    void Del_Back();

    // 获取数组容量
    int get_Capacity();

    // 获取数组当前存放元素数量
    int get_Size();

    // 析构函数
    ~MyArray();

private:
    // 数组, 因为数组数据开辟到堆区存放,因此这里用指针
    T *pAddress;

    // 数组容量,也即能存放的元素最大数量
    int m_Capacity;

    // 当前存放的数组大小
    int m_Size;

};


// 有参构造函数
template <class T>
MyArray<T>::MyArray(int capacity) {
    cout << "有参构造函数" << endl;
    this->m_Size = 0;
    this->m_Capacity = capacity;
    this->pAddress = new T[capacity];
}


// 拷贝构造函数
template <class T>
MyArray<T>::MyArray(const MyArray<T> &arr) {
    cout << "拷贝构造函数" << endl;
    this->m_Capacity = arr.m_Capacity;
    this->m_Size = arr.m_Size;
    // 深拷贝
    this->pAddress = new T[arr.m_Capacity];
    // 将arr中的元素拷贝过来
    for(int i=0; i<arr.m_Size; i++){
        this->pAddress[i] = arr.pAddress[i];
    }
}

// 赋值运算符重载
template <class T>
MyArray<T>& MyArray<T>:: operator=(const MyArray<T> &arr){
    cout << "运算符重载" << endl;
    // 先判断原来堆区是否有数据,如果有则先释放
    if(this->pAddress!=NULL){
        delete [] this->pAddress;
        this->pAddress = NULL;
        this->m_Size = 0;
        this->m_Capacity = 0;
    }
    // 深拷贝
    this->m_Capacity = arr.m_Capacity;
    this->m_Size = arr.m_Size;
    this->pAddress = new T[this->m_Capacity];
    for (int i=0; i<this->m_Size; i++){
        this->pAddress[i] = arr.pAddress[i];
    }
    // 这一步一定要返回,不然相当于赋值拷贝生成一个匿名MyArray实例,马上就又被删除了,无法赋值
    return *this;
};


// 尾插法
template <class T>
void MyArray<T>::Push_Back(const T& val){
    // 先判断数组容量是否已满
    if (this->m_Size==this->m_Capacity){
        cout << "数组已满,无法插入数据" << endl;
    }else{
        this->pAddress[m_Size] = val;
        this->m_Size ++;
    }
};

// 尾删法
template <class T>
void MyArray<T>::Del_Back() {
    // 先判断,如果数组为空,则不进行操作
    if(this->m_Size==0){
        cout << "当前数组为空!" << endl;
    }else{
        this->m_Size--;
    }
}

// 利用下标访问数组的元素, 返回引用使得可以下标赋值:arr[0]=100;
template <class T>
T& MyArray<T>::operator[](int index) {
    // 这里其实应该加个catch防止out of index
    return this->pAddress[index];

}

// 获取数组容量
template <class T>
int MyArray<T>::get_Capacity(){
    return this->m_Capacity;
}

// 获取数组当前存放元素数量
template <class T>
int MyArray<T>::get_Size(){
    return this->m_Size;
}

// 析构函数, 手动释放存在堆区的数据
template <class T>
MyArray<T>::~MyArray(){
    cout << "析构函数" << endl;
    if (this->pAddress!=NULL){
        delete [] this->pAddress;
        this->pAddress = NULL;
    }
}

测试

//
// Created by shexuan on 2021/1/17.
//

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

#include "udfArray.hpp"

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

class Person{
public:
    Person(){}; // 默认构造函数
    Person(string name, int age){
        this->m_name = name;
        this->m_age = age;
    };
    int m_age;
    string m_name;
};

template <class T>
void printArr(const MyArray<T> &arr, int len){
    for (int i=0; i<len; i++){
        cout << i << " ";
    }
    cout << endl;
}

void printUdfArr(MyArray<Person> &arr){
    for (int i=0; i<arr.get_Size(); i++){
        cout << "\t姓名:" << arr[i].m_name << "\t年龄:"<<arr[i].m_age << endl;
    }
}


void test01(){
    MyArray<int> arr1(10);
    for (int i=0;i<10;i++){
        arr1.Push_Back(i);
    }

    int len = arr1.get_Size();
    cout << len << endl;
    printArr<int> (arr1, len);
    cout << "尾删前:" << endl;
    cout << "arr1的容量为:" << arr1.get_Capacity() << endl;
    cout << "arr1的元素数量为:" << arr1.get_Size() << endl;
//    MyArray<int> arr2(arr1);
//    MyArray<int> arr3(100);
//    arr3 = arr1;
    arr1.Del_Back();
    cout << "尾删后:" << endl;
    cout << "arr1的容量为:" << arr1.get_Capacity() << endl;
    cout << "arr1的元素数量为:" << arr1.get_Size() << endl;
    printArr<int> (arr1, arr1.get_Size());
}


void test02(){
    MyArray<Person> arr(10);

    Person p1("猴哥儿", 1000);
    Person p2("八戒", 700);
    Person p3("沙师弟", 200);
    Person p4("师傅", 20);
    Person p5("菩萨", 10000);

    arr.Push_Back(p1);
    arr.Push_Back(p2);
    arr.Push_Back(p3);
    arr.Push_Back(p4);
    arr.Push_Back(p5);
    cout << "arr的容量为:" << arr.get_Capacity() << endl;
    cout << "arr的元素数量为:" << arr.get_Size() << endl;
    printUdfArr(arr);
}

int main(){
    // test01();
    test02();
}

相关文章

网友评论

      本文标题:黑马C++视频笔记《模板:类模板实战案例》

      本文链接:https://www.haomeiwen.com/subject/nkjzaktx.html