【C++】--模拟实现vector


vector和我们学数据结构时候的顺序表差不多,不过STL库里面的vector给我们提供了很多的接口函数,十分方便。对于各接口的调用这里就不详细讲解了,用到的时候不熟悉可以去官网查一下。这篇文章主要讲讲 个人对vector模拟实现的方法

image-20221124160305301

Constructors(构造函数)

vector是一个模板类,可以存储不同类型的数据。先来看看官方的几种构造法方法

image-20221124160734864

因为vector是一个模板类,所以在定义类时要用模板的格式。在vector中可以简单的定义三个类变量,全部用模板类型的指针类型

iterator _start;//首地址
iterator _finish;//最后一位有效数据的后一位地址
iterator _endofstorage;//容量的最后一位地址

template<class T>
	class myvector {
   
	public:
		typedef T* iterator;
		typedef const T* const_iterator;
        
	private:
		iterator _start;//首地址
		iterator _finish;//最后一位有效数据地址
		iterator _endofstorage;//容量的最后一位地址
	};

myvector()

定义好变量后,先实现一个无参的构造函数。因为变量都是指针类型,所以一开始我们可以将它们初始化为nullptr

myvector()
    :_start(nullptr)
    , _finish(nullptr)
    ,_endofstorage(nullptr)
{
   }

myvector(int n, const T& val = T())

再来实现一个跟库里面一样的,可以指定对象开辟的空间大小,并把指定值填入每一个空间中

myvector(int n, const T& val = T()) 
    :_start(nullptr)
    , _finish(nullptr)
    , _endofstorage(nullptr)
{
   
    reserve(n);
    for (int i = 0; i < n; i++)
    push_back(val);
}

push_back的实现下面再将。

注意:这个的缺省值不能用0或者" ",因为类型T没有确定,有可能会是我们自定义的类型,所以缺省值要使用T类型的默认初始值。参数中的n为什么不用size_t类型呢,下面会谈到

myvector(InputIterator first, InputIterator last)

接下来库里面的第三个构造函数,指定一段区间,并将这段区间的所有数值赋值到对象中。因为是一段区间,所以参数传的是指针,但是由于类型没有确定,所以要使用模板函数

template <class InputIterator>
myvector(InputIterator first, InputIterator last)
    :_start(nullptr)
    , _finish(nullptr)
    , _endofstorage(nullptr)
{
   
    while (first != last) {
   
        push_back(*first);
        first++;
    }
}

为什么上面讲的第二个构造不使用size_t类型呢,就是因为第三个区间的构造传的参数是指针类型,如果第二个参数使用的是size_t类型,那么当我们构造传参时,编译器就不知道去匹配哪一个构造函数了。所以为了避免冲突,第二个构造我们使用int类型参数。

拷贝构造

接下来实现拷贝构造函数,因为有了上面的区间构造函数后,我们只需要创建一个临时的对象,然后和原对象交换一下后就可以了。需要注意的是,交换的时候要将地址交换才不会出现野指针的情况

myvector(const myvector<T>& v)
    :_start(nullptr)
    , _finish(nullptr)
    , _endofstorage(nullptr)
{
   
    myvector<int> tmp(v.begin(), v.end());
    swap(tmp);
}

交换函数

交换地址就可以直接实现了

void swap(myvector<T>& v) {
   
    std::swap(_start, v._start);
    std::swap(_finish, v._finish);
    std::swap(_endofstorage, v._endofstorage);
}

myvector< T >& operator=(myvector< T > v)

按照我们的使用习惯,一般都会有对象给对象赋值,所以肯定少不了实现 =运算符重载了。因为形参的改变不会影响实参,所以我们只需要形参对象和原对象交换一下即可

myvector<T>& operator=(myvector<T> v) {
   
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用和提供了关于实现vector的两种方法。其中,引用展示了一个使用reserve和push_back方法的示例,而引用展示了一个使用new和memcpy函数的示例。这两种方法都是常见的实现vector的方式。 在第一种方法中,通过reserve函数可以预留足够的内存空间,然后使用push_back函数逐个将元素添加到vector中。这种方法的好处是可以避免不必要的内存重分配,提高了效率。 而第二种方法使用new操作符在堆上分配内存空间,并使用memcpy函数将已有的vector对象的数据复制到新的内存空间中。通过这种方式,可以实现深拷贝,即两个vector对象拥有独立的内存空间。这种方法的好处是可以在不修改原始vector对象的情况下创建一个新的vector对象。 除了以上两种方法,还可以使用其他方式实现vector类。例如,可以使用动态数组来实现vector的底层数据结构,然后通过成员函数实现vector的各种操作,如增加、删除、查找等。 总结来说,c语言模拟实现vector的关键是动态内存管理和对元素的增删改查操作。可以使用预留空间和逐个添加元素的方式,也可以使用动态数组和复制数据的方式来实现vector类。具体的实现方式可以根据需求和实际情况选择。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [C++——vector模拟实现](https://blog.csdn.net/weixin_49449676/article/details/126813526)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值