iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++模拟实现vector流程详解
  • 216
分享到

C++模拟实现vector流程详解

C++vector容器C++vector 2022-11-13 14:11:09 216人浏览 八月长安
摘要

目录模拟vector总结模拟vector 我们可以通过模板实现类似vector的类。我们实现一个StrVecTemp类,其内部通过allocator开辟空间,存储的类型用T来表示,T

模拟vector

我们可以通过模板实现类似vector的类。我们实现一个StrVecTemp类,其内部通过allocator开辟空间,存储的类型用T来表示,T是模板类型。

template <typename T>
class StrVecTemp
{
public:
    StrVecTemp() : elements(nullptr), first_free(nullptr),
                   cap(nullptr) {}
    //拷贝构造函数
    StrVecTemp(const StrVecTemp &);
    //拷贝赋值运算符
    StrVecTemp &operator=(const StrVecTemp &);
    //移动构造函数
    StrVecTemp(StrVecTemp &&src) noexcept : elements(src.elements),
                                            first_free(src.first_free), cap(src.cap)
    {
        //将源数据置空
        src.elements = src.first_free = src.cap = nullptr;
    }
    template <class... Args>
    void emplace_back(Args &&...args);
    //析构函数
    ~StrVecTemp();
    //拷贝元素
    void push_back(const T &);
    //抛出元素
    void pop_back(T &s);
    //返回元素个数
    size_t size() const { return first_free - elements; }
    //返回capacity返回容量
    size_t capacity() const { return cap - elements; }
    //返回首元素的指针
    T *begin() const
    {
        return elements;
    }
    //返回第一个空闲元素指针
    T *end() const
    {
        return first_free;
    }
private:
    //判断容量不足靠皮新空间
    void chk_n_alloc()
    {
        if (size() == capacity())
        {
            reallocate();
        }
    }
    //重新开辟空间
    void reallocate();
    // copy指定范围的元素到新的内存中
    std::pair<T *, T *> alloc_n_copy(const T *, const T *);
    //释放空间
    void free();
    //数组首元素的指针
    T *elements;
    //指向数组第一个空闲元素的指针
    T *first_free;
    //指向数组尾后位置的指针
    T *cap;
    //初始化alloc用来分配空间
    static std::allocator<T> alloc;
};
template <typename T>
std::allocator<T> StrVecTemp<T>::alloc;

alloc在使用前要在类外初始化,因为是模板类,所以放在.h中初始化即可。

接下来我们要实现根据迭代器开始和结束的区间copy旧元素到新的空间里

//实现区间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);
    //用旧的数据初始化新的空间
    auto first_free = uninitialized_copy(b, e, newdata);
    return {newdata, first_free};
}

实现copy构造

//实现拷贝构造函数
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;
}

实现copy赋值

//拷贝赋值运算符
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;
}

析构函数要先销毁数据再回收内存

//析构函数
template <class T>
StrVecTemp<T>::~StrVecTemp()
{
    //判断elements是否为空
    if (elements == nullptr)
    {
        return;
    }
    //缓存第一个有效元素的地址
    auto dest = elements;
    //循环析构
    for (size_t i = 0; i < size(); i++)
    {
        //析构每一个元素
        alloc.destroy(dest++);
    }
    //再回收内存
    alloc.deallocate(elements, cap - elements);
    elements = nullptr;
    cap = nullptr;
    first_free = nullptr;
}

重新开辟空间

template <class T>
void StrVecTemp<T>::reallocate()
{
    T *newdata = nullptr;
    //数组为空的情况
    if (elements == nullptr || cap == nullptr || first_free == nullptr)
    {
        newdata = alloc.allocate(1);
        elements = newdata;
        first_free = newdata;
        // cap指向数组尾元素的下一个位置
        cap = newdata + 1;
        return;
    }
    //原数据不为空,则扩充size两倍大小
    newdata = alloc.allocate(size() * 2);
    //新内存空闲位置
    auto dest = newdata;
    //就内存的有效位置
    auto src = elements;
    //通过移动操作将旧数据放到新内存中
    for (size_t i = 0; i != size(); ++i)
    {
        alloc.construct(dest++, std::move(*src++));
    }
    //移动完旧数据后一定要删除
    free();
    //更新数据位置
    elements = newdata;
    first_free = dest;
    cap = newdata + size() * 2;
}

上面的函数用到了free函数,我们自己实现一个free

template <typename T>
void StrVecTemp<T>::free()
{
    //先判断elements是否为空
    if (elements == nullptr)
    {
        return;
    }
    auto dest = elements;
    //遍历析构每一个对象
    for (size_t i = 0; i < size(); i++)
    {
        // destroy 会析构每一个元素
        alloc.destroy(dest++);
    }
    //再整体回收内存
    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);
}

接下来要实现emplace_back,因为emplace_back支持多种构造函数的参数,所以要用模板参数列表的方式定义该函数。

模板参数列表和形参列表都要用参数包的方式

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

Args是模板参数包,args是参数列表。因为construct的参数可能为右值引用,所以要用forward将原参数列表类型原样转发。

// forward既扩展了模板参数包Args,又扩展了函数参数包args
// std::forward<Args>(args)... 等价于std::forward<Ti>(ti)
//比如传递给emplace_back(10,'c');
//相当于调用 alloc.construct(first_free++, forward<int>(10), forward<char>('c'))
//调用的就是插入cccccccccc

总结

本文模拟实现了vector的功能。

视频链接

源码链接

到此这篇关于C++模拟实现vector流程详解的文章就介绍到这了,更多相关C++ vector内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++模拟实现vector流程详解

本文链接: https://www.lsjlt.com/news/172117.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++模拟实现vector流程详解
    目录模拟vector总结模拟vector 我们可以通过模板实现类似vector的类。我们实现一个StrVecTemp类,其内部通过allocator开辟空间,存储的类型用T来表示,T...
    99+
    2022-11-13
    C++ vector容器 C++ vector
  • C++超详细讲解模拟实现vector
    目录1. 模拟实现vector2. vector常用接口2.1 reserve2.2 resize2.3 push_back2.4 pop_back()2.5 insert2.6 e...
    99+
    2022-11-13
  • C++中vector的模拟实现实例详解
    目录vector接口总览 默认成员函数 构造函数 拷贝构造 赋值重载 析构函数 迭代器相关函数 begin和end 容量相关函数 size和capacity reserve resi...
    99+
    2022-11-12
  • 详解C++中vector的理解以及模拟实现
    目录vector介绍vector常见函数介绍vector模拟实现及迭代器失效讲解vector介绍 vector文档 1.vector是表示可变大小数组的序列容器。 2.就像数组一样,...
    99+
    2023-03-08
    C++ vector实现 C++ vector
  • c++ vector模拟实现的全过程
    一、vector是什么? vector是表示可变大小数组的序列容器,它也采用连续存储空间来存储元素,因此可以采用下标对vector的元素进行访问,它的大小是动态改变的,vector...
    99+
    2022-11-12
  • C++ STL vector的模拟实现
    1. vector的介绍和使用 vector是表示可变大小数组的序列容器。 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对v...
    99+
    2022-11-12
  • C++模拟实现vector的方法
    今天小编给大家分享一下C++模拟实现vector的方法的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1. 模拟实现vecto...
    99+
    2023-07-02
  • C++中如何模拟实现vector
    这篇文章给大家分享的是有关C++中如何模拟实现vector的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。vector接口总览namespace nzb{//模拟实现vectortemplate<c...
    99+
    2023-06-25
  • C++String部分成员模拟实现流程详解
    目录string类的成员设计普通构造函数的模拟拷贝构造函数的模拟赋值重载函数的模拟String的析构函数模拟补全上述的成员函数迭代器的简单模拟其他成员函数的模拟string类的成员设...
    99+
    2022-11-13
  • C++模板以及实现vector实例详解
    目录函数模板类模板Vector实现简单的类模板实现代码及测试:win msvc编译器的实现:容器的空间配置器运算符重载与迭代器实现最终vector的实现代码总结函数模板 函数模板:是...
    99+
    2022-11-12
  • C++ vector类的模拟实现方法
    vector和string虽然底层都是通过顺序表来实现的,但是他们利用顺序表的方式不同,string是指定好了类型,通过使用顺序表来存储并对数据进行操作,而vector是利用了C++...
    99+
    2022-11-12
  • C++模拟实现vector代码分析
    本篇内容主要讲解“C++模拟实现vector代码分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++模拟实现vector代码分析”吧!vector的模拟实现#include <...
    99+
    2023-07-05
  • C++  STL _ Vector使用及模拟实现
    目录1.Vector的介绍1.1 Vector的介绍2.Vector的使用2.1 vector的定义2.2 vector 迭代器的使用 2.3 vector的空间增长问题3...
    99+
    2022-11-13
  • c++中vector的使用和模拟实现
    一、接口介绍 1、插入数据 void push_back(const T& x) 在当前vector尾部插入x,如果容量不够扩大二倍。 iterator insert(it...
    99+
    2022-11-12
  • C++模拟实现vector的示例代码
    目录1.前言2.vector介绍3.vector模拟实现3.1 迭代器接口3.2 vector元素操作3. 3 构造与析构1.前言 大家在学习C++的时候一定会学到STL(标准模板库...
    99+
    2022-11-13
  • C++中STL vector的模拟实现示例
    这篇文章主要介绍C++中STL vector的模拟实现示例,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1. vector的介绍和使用vector是表示可变大小数组的序列容器。就像数组一样,vector也采用的连续存...
    99+
    2023-06-14
  • C++模拟实现vector示例代码图文讲解
    目录vector的模拟实现使用memcpy拷贝问题vector的模拟实现 #include <iostream> using namespace std; #includ...
    99+
    2023-02-27
    C++ vector模拟实现 C++ vector模拟
  • c++中vector模拟实现的示例分析
    这篇文章将为大家详细讲解有关c++中vector模拟实现的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、vector是什么?vector是表示可变大小数组的序列容器,它也采用连续存储空间来存储...
    99+
    2023-06-14
  • C++ qsort函数排序与冒泡模拟实现流程详解
    目录一、qsort排序函数1、函数功能特点2、函数参数3、比较函数4、测试qsort排序(1)测试qsort函数排序整形(2)测试qsort函数排序结构体二、冒泡模拟qusort函数...
    99+
    2022-11-13
    C++ qsort函数排序 C++冒泡排序
  • Java模拟实现HashMap算法流程详解
    目录1、前言2、成员变量的设定3、构造方法4、hash方法以及阈值判断方法5、put方法6、resize 方法7、get 方法1、前言 上期讲解了 HashMap 和 HashSet...
    99+
    2023-02-08
    Java HashMap Java模拟实现HashMap
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作