日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

C++類模板實戰之vector容器的實現_C 語言

作者:葉落秋白 ? 更新時間: 2022-08-26 編程語言

案例要求

可以對內置數據類型以及自定義數據類型的數據進行存儲

將數組中的數據存儲到堆區

構造函數中可以傳入數組的容量

提供對應的拷貝構造函數以及operator=防止淺拷貝問題

提供尾插法和尾刪法對數組中的數據進行增加和刪除

可以通過下標的方式訪問數組中的元素

可以獲取數組中當前元素個數和數組的容量

完成步驟

1、封裝數組類屬性并完成有參構造以及析構函數

#pragma once
#include<iostream>
using namespace std;
template<class T>
class Arrays
{
private:
    T* arr;//數組arr存放T類型的數據
    int capacity;//數組容量
    int size;//數組大小
public:
    Arrays(int capacity)
    {
        this->capacity = capacity;
        this->size = 0;
        this->arr = new T[this->capacity];
    }
    ~Arrays()
    {
        if (this->arr != NULL)
        {
            delete []this->arr;
            this->arr = NULL;
        }
    }
};

我把自己的這個數組類模板放到一個.hpp文件里,方便測試的時候調用。代碼第一行是為了防止頭文件重復包含,template里面的T就是數組的數據類型,根據調用時不同的指定存放不同類型的數據。將數組arr以及數組容量和大小進行封裝,寫在私有權限下即可 。然后提供該類的有參構造,參數列表傳入的是數組容量,有參構造初始化了數組的容量以及大小并將數組開辟到了堆區。析構函數就是來清理堆區數據,如果我們開辟的堆區數組不為空,那就清理掉并將其指向NULL,這樣可以防止野指針出現,避免異常。

2、提供對應的深拷貝構造函數防止調用析構時出錯

    Arrays(const Arrays& p)
    {
        this->capacity = p.capacity;
        this->size = p.size;
        this->arr = new T[p.capacity];
        for (int i = 0; i < this->size; i++)
        {
            this->arr[i] = p.arr[i];
        }
    }

如果不提供深拷貝,那么編譯器就會有:this->arr=p->arr 這行代碼 ,那么一旦我們調用編譯器提供的淺拷貝,當運行到析構函數時,就會出現重復刪除地址的情況,必然會出現程序錯誤。所以我們要自己提供深拷貝構造函數,將上面的代碼改為 this->arr= new T[p.capacity] ,這樣調用析構的時候各自刪除各的堆區數據,不會出現上述情況。最后利用for循環將傳進來的對象的數據賦值給新開辟的數組。

3、重載類內的賦值運算符防止淺拷貝問題出現

    Arrays& operator=(const Arrays& p)
    {
        if (this->arr!=NULL)
        {
            delete []this->arr;
            this->arr = NULL;
            this->capacity = 0;
            this->size = 0;
        }
        //深拷貝過程
        this->capacity = p.capacity;
        this->size = p.size;
        this->arr = new T[this->capacity];
        for (int i = 0; i < p.size; i++)
        {
            this->arr[i] = p.arr[i];
        }
        return *this;
    }

當數組數據是對象的類型時,不能簡單的將數組進行賦值操作,因為也牽扯到直接賦值出現一樣的數組地址的情況,存在著深淺拷貝問題。賦值的時候是將傳入參數的數據賦值給自己,因此先把自己的屬性清空,然后就是深拷貝的實現了。最后返回的是*this,this指針能夠指向不同成員屬性,那么*this就是對象本身,然后看到返回值類型是對象引用,這樣就可以實現對象間的連續賦值了。

4、提供尾部插入和刪除的方法

    void insert_Arrays(const T&value)
    {
        if (this->capacity == this->size)
        {
            return;
        }
        this->arr[size] = value;
        this->size++;
    }
    void delete_Arrays()
    {
        if (this->size == 0)
        {
            return;
        }
        this->size--;
    }

尾插過程:先判斷數組是否已經滿了,如果不滿就將形參賦值給當前數組最后一個下標的位置,然后更新數組下標,這樣就能保證每次插入的數據都在數組末尾。?

尾刪的實現:先判斷數組是否為空,不為空的時候直接把數組大小減一即可,讓編譯器訪問不到當前的最后一個數組元素。注意尾刪的只是數據的指針,數組的地址并未刪除。

5、重載[]得到數組中對應下標的數據信息

    T& operator[](int index)
    {
        return this->arr[index];
    }

如果數組內容是對象類型,是不存在對象數組的,所以要對[]運算符進行重載。返回值類型為數據類型的引用,也就是具體的數組內的值,傳進去的整型參數就是數組下標。

6、提供get方法獲取當前數組容量及大小

    int getSize()
    {
        return this->size;
    }
    int getCapacity()
    {
        return this->capacity;
    }

這里就是經典的get方法了,返回對應封裝的成員屬性 ,不做多解釋。

7、提供打印函數測試基本數據類型和自定義數據類型的存儲

#include"arrays.hpp"
class Hero
{
    friend void printHero(Arrays<Hero>&hero);
private:
    string name;
    string position;
public:
    Hero() {}
    Hero(string name, string position)
    {
        this->name = name;
        this->position = position;
    }
};
void printArrays(Arrays<int>arr)
{
    for (int i = 0; i < arr.getSize(); i++)
    {
        cout << arr[i] << " ";
    }
    cout << endl;
}
void printHero(Arrays<Hero>&hero)
{
    for (int i = 0; i < hero.getSize(); i++)
    {
        cout << "姓名:"<<hero[i].name<<" 位置:"<<hero[i].position<<endl;
    }
}
void test()
{
    cout << "普通類型數組測試:" << endl;
    cout << "輸入數組容量為:" ;
    int n = 0; cin >> n;
    Arrays<int> array(n);
    cout << "輸入數據:";
    for (int i = 0; i < array.getCapacity(); i++)
    {
        int value = 0;
        cin >> value;
        array.insert_Arrays(value);
    }
    cout << "打印數組信息:"<<endl;
    printArrays(array);
    array.delete_Arrays();
    cout << "刪除一次尾部數據后打印數組信息:" << endl;
    printArrays(array);
}
void test1()
{
    cout << "自定義類型數組測試:" << endl;
    Hero h1("火舞","中單");
    Hero h2("韓信","打野");
    Hero h3("桑啟","游走");
    Hero h4("守約","發育");
    Hero h5("關羽","對抗");
    Arrays<Hero> array(5);
    array.insert_Arrays(h1);
    array.insert_Arrays(h2);
    array.insert_Arrays(h3);
    array.insert_Arrays(h4);
    array.insert_Arrays(h5);
    printHero(array);
    array.delete_Arrays();
    cout << "刪除一次尾部數據后打印數組信息:"<<endl;
    printHero(array);
}

首先引入之前封裝的數組類頭文件,提供printArrays和printHero函數來進行數組信息的打印,test和test1函數分別是整型數組和對象數組的測試。接下來看運行效果。

運行效果:

原文鏈接:https://blog.csdn.net/m0_58618795/article/details/125592238

欄目分類
最近更新