最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++模擬實(shí)現(xiàn)vector流程詳解

 更新時(shí)間:2022年08月08日 15:46:29   作者:戀戀風(fēng)辰  
這篇文章主要介紹了C++容器Vector的模擬實(shí)現(xiàn),Vector是一個(gè)能夠存放任意類型的動(dòng)態(tài)數(shù)組,有點(diǎn)類似數(shù)組,是一個(gè)連續(xù)地址空間,下文更多詳細(xì)內(nèi)容的介紹,需要的小伙伴可以參考一下

模擬vector

我們可以通過模板實(shí)現(xiàn)類似vector的類。我們實(shí)現(xiàn)一個(gè)StrVecTemp類,其內(nèi)部通過allocator開辟空間,存儲(chǔ)的類型用T來表示,T是模板類型。

template <typename T>
class StrVecTemp
{
public:
    StrVecTemp() : elements(nullptr), first_free(nullptr),
                   cap(nullptr) {}
    //拷貝構(gòu)造函數(shù)
    StrVecTemp(const StrVecTemp &);
    //拷貝賦值運(yùn)算符
    StrVecTemp &operator=(const StrVecTemp &);
    //移動(dòng)構(gòu)造函數(shù)
    StrVecTemp(StrVecTemp &&src) noexcept : elements(src.elements),
                                            first_free(src.first_free), cap(src.cap)
    {
        //將源數(shù)據(jù)置空
        src.elements = src.first_free = src.cap = nullptr;
    }
    template <class... Args>
    void emplace_back(Args &&...args);
    //析構(gòu)函數(shù)
    ~StrVecTemp();
    //拷貝元素
    void push_back(const T &);
    //拋出元素
    void pop_back(T &s);
    //返回元素個(gè)數(shù)
    size_t size() const { return first_free - elements; }
    //返回capacity返回容量
    size_t capacity() const { return cap - elements; }
    //返回首元素的指針
    T *begin() const
    {
        return elements;
    }
    //返回第一個(gè)空閑元素指針
    T *end() const
    {
        return first_free;
    }
private:
    //判斷容量不足靠皮新空間
    void chk_n_alloc()
    {
        if (size() == capacity())
        {
            reallocate();
        }
    }
    //重新開辟空間
    void reallocate();
    // copy指定范圍的元素到新的內(nèi)存中
    std::pair<T *, T *> alloc_n_copy(const T *, const T *);
    //釋放空間
    void free();
    //數(shù)組首元素的指針
    T *elements;
    //指向數(shù)組第一個(gè)空閑元素的指針
    T *first_free;
    //指向數(shù)組尾后位置的指針
    T *cap;
    //初始化alloc用來分配空間
    static std::allocator<T> alloc;
};
template <typename T>
std::allocator<T> StrVecTemp<T>::alloc;

alloc在使用前要在類外初始化,因?yàn)槭悄0孱?,所以放?h中初始化即可。

接下來我們要實(shí)現(xiàn)根據(jù)迭代器開始和結(jié)束的區(qū)間copy舊元素到新的空間里

//實(shí)現(xiàn)區(qū)間copy
template <typename T>
std::pair<T *, T *> StrVecTemp<T>::alloc_n_copy(const T *b, const T *e)
{
    auto newdata = alloc.allocate(e - b);
    //用舊的數(shù)據(jù)初始化新的空間
    auto first_free = uninitialized_copy(b, e, newdata);
    return {newdata, first_free};
}

實(shí)現(xiàn)copy構(gòu)造

//實(shí)現(xiàn)拷貝構(gòu)造函數(shù)
template <class T>
StrVecTemp<T>::StrVecTemp(const StrVecTemp &strVec)
{
    auto rsp = alloc_n_copy(strVec.begin(), strVec.end());
    //利用pair類型更新elements, cap, first_free
    elements = rsp.first;
    first_free = rsp.second;
    cap = rsp.second;
}

實(shí)現(xiàn)copy賦值

//拷貝賦值運(yùn)算符
template <class T>
StrVecTemp<T> &StrVecTemp<T>::operator=(const StrVecTemp &strVec)
{
    if (this == &strVec)
    {
        return *this;
    }
    //如果不是自賦值,就將形參copy給自己
    auto rsp = alloc_n_copy(strVec.begin(), strVec.end());
    elements = rsp.first;
    first_free = rsp.second;
    cap = rsp.second;
}

析構(gòu)函數(shù)要先銷毀數(shù)據(jù)再回收內(nèi)存

//析構(gòu)函數(shù)
template <class T>
StrVecTemp<T>::~StrVecTemp()
{
    //判斷elements是否為空
    if (elements == nullptr)
    {
        return;
    }
    //緩存第一個(gè)有效元素的地址
    auto dest = elements;
    //循環(huán)析構(gòu)
    for (size_t i = 0; i < size(); i++)
    {
        //析構(gòu)每一個(gè)元素
        alloc.destroy(dest++);
    }
    //再回收內(nèi)存
    alloc.deallocate(elements, cap - elements);
    elements = nullptr;
    cap = nullptr;
    first_free = nullptr;
}

重新開辟空間

template <class T>
void StrVecTemp<T>::reallocate()
{
    T *newdata = nullptr;
    //數(shù)組為空的情況
    if (elements == nullptr || cap == nullptr || first_free == nullptr)
    {
        newdata = alloc.allocate(1);
        elements = newdata;
        first_free = newdata;
        // cap指向數(shù)組尾元素的下一個(gè)位置
        cap = newdata + 1;
        return;
    }
    //原數(shù)據(jù)不為空,則擴(kuò)充size兩倍大小
    newdata = alloc.allocate(size() * 2);
    //新內(nèi)存空閑位置
    auto dest = newdata;
    //就內(nèi)存的有效位置
    auto src = elements;
    //通過移動(dòng)操作將舊數(shù)據(jù)放到新內(nèi)存中
    for (size_t i = 0; i != size(); ++i)
    {
        alloc.construct(dest++, std::move(*src++));
    }
    //移動(dòng)完舊數(shù)據(jù)后一定要?jiǎng)h除
    free();
    //更新數(shù)據(jù)位置
    elements = newdata;
    first_free = dest;
    cap = newdata + size() * 2;
}

上面的函數(shù)用到了free函數(shù),我們自己實(shí)現(xiàn)一個(gè)free

template <typename T>
void StrVecTemp<T>::free()
{
    //先判斷elements是否為空
    if (elements == nullptr)
    {
        return;
    }
    auto dest = elements;
    //遍歷析構(gòu)每一個(gè)對(duì)象
    for (size_t i = 0; i < size(); i++)
    {
        // destroy 會(huì)析構(gòu)每一個(gè)元素
        alloc.destroy(dest++);
    }
    //再整體回收內(nèi)存
    alloc.deallocate(elements, cap - elements);
    elements = nullptr;
    cap = nullptr;
    first_free = nullptr;
}

壓入元素和彈出元素

//拷貝元素
template <class T>
void StrVecTemp<T>::push_back(const T &t)
{
    chk_n_alloc();
    alloc.construct(first_free++, t);
}
//拋出元素
template <class T>
void StrVecTemp<T>::pop_back(T &s)
{
    //先判斷是否為空
    if (first_free == nullptr)
    {
        return;
    }
    //判斷size為1
    if (size() == 1)
    {
        s = *elements;
        alloc.destroy(elements);
        first_free = nullptr;
        elements = nullptr;
        return;
    }
    s = *(--first_free);
    alloc.destroy(first_free);
}

接下來要實(shí)現(xiàn)emplace_back,因?yàn)閑mplace_back支持多種構(gòu)造函數(shù)的參數(shù),所以要用模板參數(shù)列表的方式定義該函數(shù)。

模板參數(shù)列表和形參列表都要用參數(shù)包的方式

template <class T>
template <class... Args>
void StrVecTemp<T>::emplace_back(Args &&...args)
{
    chk_n_alloc();
    alloc.construct(first_free++, forward<Args>(args)...);
}

Args是模板參數(shù)包,args是參數(shù)列表。因?yàn)閏onstruct的參數(shù)可能為右值引用,所以要用forward將原參數(shù)列表類型原樣轉(zhuǎn)發(fā)。

// forward既擴(kuò)展了模板參數(shù)包Args,又?jǐn)U展了函數(shù)參數(shù)包args
// std::forward<Args>(args)... 等價(jià)于std::forward<Ti>(ti)
//比如傳遞給emplace_back(10,'c');
//相當(dāng)于調(diào)用 alloc.construct(first_free++, forward<int>(10), forward<char>('c'))
//調(diào)用的就是插入cccccccccc

總結(jié)

本文模擬實(shí)現(xiàn)了vector的功能。

視頻鏈接

源碼鏈接

到此這篇關(guān)于C++模擬實(shí)現(xiàn)vector流程詳解的文章就介紹到這了,更多相關(guān)C++ vector內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++ 三種繼承方式及好處示例詳解

    C++ 三種繼承方式及好處示例詳解

    這篇文章主要為大家介紹了C++ 三種繼承方式及好處示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • C/C++實(shí)現(xiàn)全排列算法的示例代碼

    C/C++實(shí)現(xiàn)全排列算法的示例代碼

    本文主要介紹了C/C++實(shí)現(xiàn)全排列算法的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-06-06
  • 詳解c語(yǔ)言中的 strcpy和strncpy字符串函數(shù)使用

    詳解c語(yǔ)言中的 strcpy和strncpy字符串函數(shù)使用

    strcpy 和strcnpy函數(shù)是字符串復(fù)制函數(shù)。接下來通過本文給大家介紹c語(yǔ)言中的strcpy和strncpy字符串函數(shù)使用,感興趣的朋友跟隨小編要求看看吧
    2018-10-10
  • zlib庫(kù)壓縮和解壓字符串STL string的實(shí)例詳解

    zlib庫(kù)壓縮和解壓字符串STL string的實(shí)例詳解

    這篇文章主要介紹了zlib庫(kù)壓縮和解壓字符串STL string的實(shí)例詳解的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-10-10
  • C++關(guān)于樹的定義全面梳理

    C++關(guān)于樹的定義全面梳理

    樹是一種重要的非線性數(shù)據(jù)結(jié)構(gòu),直觀地看,它是數(shù)據(jù)元素(在樹中稱為結(jié)點(diǎn))按分支關(guān)系組織起來的結(jié)構(gòu),很象自然界中的樹那樣。樹結(jié)構(gòu)在客觀世界中廣泛存在,如人類社會(huì)的族譜和各種社會(huì)組織機(jī)構(gòu)都可用樹形象表示,本篇介紹二叉樹的遞歸與非遞歸遍歷的方法
    2022-06-06
  • c++實(shí)現(xiàn)俄羅斯方塊游戲代碼

    c++實(shí)現(xiàn)俄羅斯方塊游戲代碼

    大家好,本篇文章主要講的是c++實(shí)現(xiàn)俄羅斯方塊游戲代碼,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-01-01
  • 基于C語(yǔ)言實(shí)現(xiàn)的TCP服務(wù)器的流程分析

    基于C語(yǔ)言實(shí)現(xiàn)的TCP服務(wù)器的流程分析

    本文詳細(xì)介紹了如何使用C語(yǔ)言編寫一個(gè)簡(jiǎn)單的TCP服務(wù)器,包括創(chuàng)建套接字、綁定IP和端口、監(jiān)聽連接請(qǐng)求、接受客戶端連接、數(shù)據(jù)接收與發(fā)送以及關(guān)閉套接字等步驟,最后通過一個(gè)簡(jiǎn)單的示例展示了TCP服務(wù)器的基本實(shí)現(xiàn)過程
    2024-10-10
  • C++超詳細(xì)探究new/delete的使用

    C++超詳細(xì)探究new/delete的使用

    這篇文章主要介紹了C++中new與deleted關(guān)鍵字的使用,new在動(dòng)態(tài)內(nèi)存中為對(duì)象分配空間并返回一個(gè)指向該對(duì)象的指針;delete接受一個(gè)動(dòng)態(tài)對(duì)象的指針, 銷毀該對(duì)象, 并釋放與之關(guān)聯(lián)的內(nèi)存
    2022-07-07
  • C++?容器中map和unordered?map區(qū)別詳解

    C++?容器中map和unordered?map區(qū)別詳解

    這篇文章主要為大家介紹了C++?容器中map和unordered?map區(qū)別示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • C++中全局變量的初始化全過程

    C++中全局變量的初始化全過程

    這篇文章主要介紹了C++全局變量的初始化全過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08

最新評(píng)論

新乡市| 昌乐县| 舞阳县| 安达市| 哈密市| 石河子市| 商洛市| 阿瓦提县| 盐津县| 武胜县| 和平区| 探索| 临汾市| 体育| 万源市| 尉氏县| 房山区| 潞西市| 柳州市| 衢州市| 福泉市| 兴山县| 车险| 岳阳县| 汤原县| 山西省| 贡嘎县| 广饶县| 万全县| 黄冈市| 普陀区| 云南省| 连南| 德清县| 昭通市| 伽师县| 泰兴市| 兰州市| 泾源县| 繁昌县| 桐庐县|