【C++】容器篇(一)—— vector 的基本概述以及模拟实现

这篇具有很好参考价值的文章主要介绍了【C++】容器篇(一)—— vector 的基本概述以及模拟实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言:

在之前,我们已经对 string类进行了基本的概述,并且手动的实现了string类中常用的接口函数。本期,我将带领大家学习的是STL库中的一个容器 -- vector 的学习。相比于之前的string类,本期的 vector 相对来说实现起来略微难一点,难点就在于要考虑关于 “迭代器失效”方面和“深浅拷贝”的问题。


文章目录

前言

(一)基本介绍

1、相关定义

2、vector的引入

3、vector的优点

4、vector使用本质

(二)vector的使用

1、vector的定义

 2、vector iterator 的使用

3、vector的空间增长

 4、vector的增删查改

(三)接口函数的介绍

1、Member functions

1️⃣n个val构造

2️⃣迭代区间构造

3️⃣拷贝构造

2、Iterators

1️⃣begin()和end()

2️⃣rbegin()和rend()

3、Capacity

(四)vector模拟实现

1、成员变量

2、成员函数

1️⃣构造函数

2️⃣析构函数

3️⃣拷贝构造

3、迭代器

1️⃣begin() 和 end()

4、容量

1️⃣size()

2️⃣capacity()

3️⃣empty()

4️⃣reserve()

5️⃣resize()

5、元素访问

1️⃣operator[]

6、修改

1️⃣push_back()

2️⃣pop_back()

3️⃣insert()

4️⃣erase()

5️⃣swap()

总结


前言

在正式的学习之前,我们先来看看STL库中的容器有哪些,让大家先混个脸熟,在接下来,对于其他的容器我也会给大家进行相关的讲解。

  • STL库中的容器如下(勾画的接下来我都会给大家讲解):

【C++】容器篇(一)—— vector 的基本概述以及模拟实现

💨 而对于 map、set等则是要等到之后在给大家讲解,因为要涉及关于 红黑树的相关知识;

💨 而对于像第一个【arry】这个我们十分的熟悉了,就没有必要在进行讲解了,而【deque】和【queue】二者之间也有很多的不同之处;

💨 而对于【bitset】(位集),我们只需简单的了解即可,它主要的功能是提供一些成员函数,使程序员不必通过位运算就能很方便地访问、修改其中的任意一位


(一)基本介绍

1、相关定义

既然要学习vector,那么首先就需要知道到底什么是vector,定义如下:

  • vector是STL库中的一种序列式容器事实上和数组差不多(但它比数组更优越),由于其大小(size)可变,常用于数组大小不可知的情况下来替代数组。
  • 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素 进行访问,和数组一样高效。

2、vector的引入

  1. 一般来说数组不能动态拓展,因此在程序运行的时候不是浪费内存,就是造成越界
  2. 而 vector 正好弥补了这个缺陷,它不像数组那样,它的大小是可以动态改变的,相当于可拓展的数组(动态数组),它的随机访问快,在中间插入和删除慢,但在末端插入和删除快,而且它的大小会被容器自动处理。

3、vector的优点

  1. 与其它动态序列容器相比(deque, list and forward_list), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效;
  2. 对于其它不在末尾的删除和插入操作,效率更低;
  3. 比起list 和 forward_list 统一的迭代器和引用更好。

4、vector使用本质

本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。

其做法是:分配一个新的数组,然后将全部元素移到这个数组。

就时间而言,这是 一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。


(二)vector的使用

vector学习时一定要学会查看文档:vector的文档介绍,vector在实际中非常的重要,在实际中我们熟悉常见的接口就可以,下面列出了哪些接口是要重点掌握的。

1、vector的定义

【C++】容器篇(一)—— vector 的基本概述以及模拟实现

 2、vector iterator 的使用

【C++】容器篇(一)—— vector 的基本概述以及模拟实现

3、vector的空间增长

【C++】容器篇(一)—— vector 的基本概述以及模拟实现

 4、vector的增删查改

【C++】容器篇(一)—— vector 的基本概述以及模拟实现

大家通过文档不难发现,vector容器跟之前学习的string类的接口很相似。因此,通过之前对string的学习,并且掌握的话对于本次学习的vector学习到掌握是很容易的!!!


(三)接口函数的介绍

接下来,我就将为大家介绍常用的接口以及实现的过程!!!

1、Member functions

对于构造,我们通过阅读文档可以发现,文档给出的构造有四种,分别是:

  • 默认构造
  • n个val构造
  • 迭代区间构造
  • 拷贝构造

【C++】容器篇(一)—— vector 的基本概述以及模拟实现


接下来,我直接给大家展示相关方法是如何进行函数构造的。 

1️⃣n个val构造

  • 代码如下:
void test1()
{
	//n个val构造
	vector<int>arr(10,1); //ten ints with value 1

	for (int i = 0; i < arr.size(); ++i)
	{
		cout << arr[i] << " ";
	}
	cout << endl;

}

int main()
{
	test1();
	return 0;
}
  • 解释说明:

上述代码我们构造包含 10个元素的容器。每个元素都是 的副本。


2️⃣迭代区间构造

  • 代码如下:
void test()
{
    vector<int>arr(10,1);

	//迭代区间构造
	vector<int>tmp(arr.begin(), arr.end());
	for (int i = 0; i < tmp.size(); ++i)
	{
		cout << tmp[i] << " ";
	}
	cout << endl;

}

int main()
{
	test();
	return 0;
}
  • 解释说明:

 上述通过构造一个容器,其中包含与范围 [first、last)(特别注意迭代区间的范围是左闭右开) 一样多的元素,每个元素都以相同的顺序从该区域中的相应元素构造。

拓展说明:

对于迭代器构造,不知道大家有没有发现文档中给出的描述:

【C++】容器篇(一)—— vector 的基本概述以及模拟实现

迭代器不应该叫做【iterator】吗,这里怎么叫做【inputiterator】呢?

  1. 这就要说到一个问题了,那就是迭代器是分类型的(说起来很复杂,我简单讲一下)。
  2. 不同的迭代器除了之前说过的正向、反向 这样的使用属性之外,还有相关的特性属性,比如双向、单向等;
  3. 因此在这里就表示你使用时即可传单向,也可以传双向,以及随机等(即可以传任意类型) 

例如以下:

    string str("have a good day");
	vector<int>vv(str.begin(), str.end());
	for (int i = 0; i < vv.size(); ++i)
	{
		cout << vv[i] << " ";
	}
	cout << endl;

输出的即是对应的 ASCll 码值。除此之外,还可以进行【++】或【--】操作。 


3️⃣拷贝构造

  • 代码如下:
void test()
{
	vector<int>arr;  //默认构造
	arr.push_back(1);
	arr.push_back(2);
	arr.push_back(3);
	arr.push_back(4);
	arr.push_back(5);


	//拷贝构造
	vector<int> tmp(arr);
	for (auto e : tmp)
	{
		cout << e << " ";
	}
	cout << endl;
}
  • 解释说明:

复制构造函数,以相同的顺序构造一个容器,其中包含 arr 中每个元素的副本。


2、Iterators

接下来就是关于正向迭代器和反向迭代器的介绍,这个我相信大家在之前的学习中都有了解,我就不过多阐述。

1️⃣begin()和end()

  • 代码如下:
void test()
{
	vector<int>arr;
	arr.push_back(1);
	arr.push_back(2);
	arr.push_back(3);
	arr.push_back(4);
	arr.push_back(5);


	vector<int>::iterator it = arr.begin();
	while (it != arr.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;
}

2️⃣rbegin()和rend()

  • 代码如下:
void test()
{
	vector<int>arr;
	arr.push_back(1);
	arr.push_back(2);
	arr.push_back(3);
	arr.push_back(4);
	arr.push_back(5);

	vector<int>::reverse_iterator rit = arr.rbegin();
	//auto rit = arr.rbegin();

	while (rit != arr.rend())
	{
		cout << *rit << " ";
		rit++;
	}
	cout << endl;
}

3、Capacity

对于容量的相关接口,跟之前学的string是类似的。

这里需要讲明的一点是关于 【capacity】扩容的问题,capacity的代码在 vs 和 g++ 下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。 这个问题经常会考察,不要固化的认为,vector增容都是2倍,具体增长多少是根据具体的需求定义 的。vs是PJ版本STL,g++是SGI版本STL。

  • 用以下测试代码分别在两种环境下运行后:
// 测试vector的默认扩容机制
void TestVectorExpand()
{
	size_t sz;
	vector<int> v;
	sz = v.capacity();
	cout << "making v grow:\n";
	for (int i = 0; i < 100; ++i)
	{
		v.push_back(i);
		if (sz != v.capacity())
		{
			sz = v.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}
}
  • 在vs下的结果:

【C++】容器篇(一)—— vector 的基本概述以及模拟实现

  •  在g++下的结果:

【C++】容器篇(一)—— vector 的基本概述以及模拟实现

接下来,对于reserve 和 resize,我们在后面的接口函数模拟实现上具体的讲解,以及带大家来理解迭代器失效的问题!!


(四)vector模拟实现

1、成员变量

我这里的实现风格整体来说是按照库里面的实现方式来进行操作的(如果大家有兴趣,可以去库里面看下源码)

  • 首先,我们这里实现的vector是 typedef出来的,具体如下(分为普通版本和const版本):
typedef T* iterator;
typedef const T* const_iterator;
  • 而对于类的成员变量如下: 
private:
		iterator _start;
		iterator _end;
		iterator _end_of_storage;
  • 解释说明:

 ⚔️ _start:表示指向数据的开始位置;

 ⚔️ _end:表示指向数据的结尾位置的下一个位置;

 ⚔️ _end_of_storage:表示的是整个空间的大小。

【C++】容器篇(一)—— vector 的基本概述以及模拟实现


2、成员函数

1️⃣构造函数

这些都跟之前是一样的,在这里就不多说了,具体如下:

        vector()
			: _start(nullptr)
			, _end(nullptr)
			, _end_of_storage(nullptr)
		{}

2️⃣析构函数


		~vector()
		{
			if (_start)
			{
				delete[] _start;
				_end = _end_of_storage = _start = nullptr;
			}
		}

3️⃣拷贝构造

  • 现代写法:
        //现代写法
		vector(const vector<T>& arr)
		{
			vector<int> tmp(arr.begin().arr.end());
			swap(tmp);
		}
  •  传统写法:
        vector(const vector<T>& arr)
		{
			_start = new T[arr.capacity()];
			for (size_t i = 0; i < arr.size(); ++i)
			{
				_start[i] = arr._start[i];
			}

			_end = _start + arr.size();
			_end_of_storage = _start + arr.capacity();
		}

3、迭代器

1️⃣begin() 和 end()

这里我提供了两个版本的,分别是普通版本和const版本的实现。

  • 具体如下:
        iterator begin()
		{
			return _start;
		}

		iterator end()
		{
			return _end;
		}

		const_iterator begin()const
		{
			return _start;
		}

		const_iterator end()const
		{
			return _end;
		}

对于反向迭代器,我放在之后的学习中再去讲解,因为将会涉及一些其他的东西在里面。


4、容量

1️⃣size()

理解这应该很容易理解,对于有效位数据位的大小,就为【_end】位置与【_start】位置的距离为多少。

  • 具体如下:
        //长度大小
		size_t size()const
		{
			return _end - _start;
		}

2️⃣capacity()

理解对于数据所占空间的大小,就为首元素位置与整体空间大小的差值。

  • 具体如下:
        //空间大小
		size_t capacity()const
		{
			return _end_of_storage - _start;
		}

3️⃣empty()

  • 具体如下:
        bool empty()
		{
			return _start ==  _end;
		}

4️⃣reserve()

特点reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题。

  • 代码展示:
void reserve(size_t n)
		{
			//首先先判断是否需要开辟新空间
			if (n > capacity())
			{
				//开新空间
				T* tmp = new T[n];
				if (_start)
				{
					//元素拷贝到新空间
					memcpy(tmp, _start, sizeof(T)*size());
					//释放旧空间
					delete[] _start;
				}


				_start = tmp;
				_end = tmp + size();
				_end_of_storage = tmp + n;
			}
		}

上述模拟实现的vector中的reserve接口中,会使用 memcpy 进行的拷贝,但是大家通过代码有没有发现什么问题呢?

  • 当我们用测试用例去打印结果的时候,会发生程序挂掉了:

【C++】容器篇(一)—— vector 的基本概述以及模拟实现

  •  我们通过调试去观察是什么原因导致的问题,具体如下:

【C++】容器篇(一)—— vector 的基本概述以及模拟实现

 现象解释:

  1. 首先,我们知道size() = _end - _start;
  2. 按理说释放之后应该为0,因为 tmp=_start,因此我们可以把上述带入公式带入代码中换掉,我们就不难得出一点,此时代码就为 【tmp + _end - _start(tmp) 】,所以此时最终为0了;
  3. 相当于_start 是一个地址,而最终却是 0 减 一个地址。即_end 还是之前的,而_start 却不是之前的_start 了;
  4. 因此,最好的解决办法就是在事先保留一份最初的 size() 即可。
  • 代码如下:
        void reserve(size_t n)
		{
			//首先先判断是否需要开辟新空间
			if (n > capacity())
			{
				size_t num = size();
				//开新空间
				T* tmp = new T[n];
				if (_start)
				{
					//元素拷贝到新空间
					memcpy(tmp, _start, sizeof(T)*size());
					//释放旧空间
					delete[] _start;
				}

				_start = tmp;
				_end = _start + num;
				_end_of_storage = _start + n;

			}
		}

最终通过上诉我们得出一点:

  1. 如果拷贝的是 自定义类型的元素,memcpy既高效又不会出错;
  2. 但如果拷贝的是自定义类型元素,并且自定义类型元素中涉及到资源管理时,就会出错,因为memcpy的拷贝实际是浅拷贝

 【C++】容器篇(一)—— vector 的基本概述以及模拟实现

结论:如果对象中涉及到资源管理时,千万不能使用memcpy进行对象之间的拷贝,因为memcpy是 浅拷贝,否则可能会引起内存泄漏甚至程序崩溃。

5️⃣resize()

resize在开空间的同时还会进行初始化,影响size。

  • 代码展示:
        void resize(size_t n, const T& val = T())
		{
			if (n < size())
			{
				_end = _start + n;
			}
			else
			{
				if(n > capacity())
					reserve(n);

				while (_end != _start + n)
				{
					_end = val;
					++_end;
				}
			}
		}
  • 注意这里的val初始化时初始化为 T();
  • 当单独使用T()时,当前行结束就会自动调用销毁,而当时用 const  T& val =T() 就可以延长生命周期。

5、元素访问

1️⃣operator[]

  • 代码展示:
        T& operator[](size_t pos)
		{
			assert(pos < size());

			return _start[pos];
		}

		const T& operator[](size_t pos)const
		{
			assert(pos < size());

			return _start[pos];
		}

6、修改

1️⃣push_back()


		//尾插
		void push_back(const T& X)
		{
			//先判断空间
			if (_end == _end_of_storage)
			{
				reserve(capacity() == 0 ? 4 : capacity() * 2);
			}

			//移动元素
			*_end = X;
			++_end;
		}

2️⃣pop_back()

        void pop_back()
		{
			assert(!empty()); //注意判空
			 --_end;
		}

3️⃣insert()

意思很简单,即在 pos 位置出插入 val 元素即可。但是这里却有一个很坑的点,那就是不小心写出来的代码就会引起迭代器失效的问题。

  • 大家先看以下代码:
        void insert(iterator pos, const T& val)
		{
			assert(pos >= _start);
			assert(pos <= _end);

			if (_end == _end_of_storage)
			{
				reserve(capacity() == 0 ? 4 : capacity() * 2);
			}

			iterator finish = _end - 1;
			while (finish >= pos)
			{
				*(finish + 1) = *finish;
				--finish;
			}

			*pos = val;
			++_end;
		}

此时,数组中只有4个元素(即数组中有四个元素),当我们想在第三个位置处插入元素0时,我们打印对应的结果,就会发现结果报错:

【C++】容器篇(一)—— vector 的基本概述以及模拟实现

但是,当我们提前先把 5 也放入数组(即数组中有5个元素),此时再去进行插入操作时,结果又是正确的:

【C++】容器篇(一)—— vector 的基本概述以及模拟实现

 那么上述是什么问题导致的呢?我们先调试看看:

【C++】容器篇(一)—— vector 的基本概述以及模拟实现

 解释说明:

  • 通过上述我们不难看出一个问题,程序只走了一步扩容操作,pos 位置此时没有发生变化,而 _start 和 _end 已经发送改变了。
  • 此时这种情况就是一种经典的迭代器失效现象

【C++】容器篇(一)—— vector 的基本概述以及模拟实现

解决方法:

  • 我们需要更新 pos位置 ,根据相对位置来判断扩容之后处于新空间的位置是多少。
  • 纠正写法:
        void insert(iterator pos, const T& val)
		{
			assert(pos >= _start);
			assert(pos <= _end);

			if (_end == _end_of_storage)
			{
				size_t len = pos - _start;  //迭代器失效问题(野指针)
				reserve(capacity() == 0 ? 4 : capacity() * 2);

				pos = _start + len;

			}

			iterator finish = _end - 1;
			while (finish >= pos)
			{
				*(finish + 1) = *finish;
				--finish;
			}

			*pos = val;
			++_end;
		}

但是上述改了之后是不是就 ok l呢?其实并不是的,程序其实还有 bug。

此时,很多小伙伴就会说我都已经更新了pos呀,但是我们经过调试之后发现没有起作用在这里:

【C++】容器篇(一)—— vector 的基本概述以及模拟实现

 解释说明:

  • 最主要的原因就是这里是值传递,形参的改变是不会改变实参的,所以说外面的pos依旧没有实现更新操作,依旧会失效。

 💨  正确写法是通过返回值去解决问题的,返回的是迭代器,即新插入元素的位置

  • 正确代码:
        iterator  insert(iterator pos, const T& val)
		{
			assert(pos >= _start);
			assert(pos <= _end);

			if (_end == _end_of_storage)
			{
				size_t len = pos - _start;  //迭代器失效问题(野指针)
				reserve(capacity() == 0 ? 4 : capacity() * 2);
				pos = _start + len;
			}

			iterator finish = _end - 1;
			while (finish >= pos)
			{
				*(finish + 1) = *finish;
				--finish;
			}

			*pos = val;
			++_end;

			return pos;
		}

4️⃣erase()

这里主要的就是从后往前删除的,这点需要大家注意一下。

  • 代码如下:
        void erase(iterator pos)
		{
			assert(pos >= _start);
			assert(pos < _end);

			iterator start = pos + 1;
			while (start != _end)
			{
				*(start - 1) = *start;
				++start;
			}
			--_end;
		}

此时问题又来了,上述这样写会不会也有迭代器失效的问题呢?

 💨  首先,我们简单的测试一下:

【C++】容器篇(一)—— vector 的基本概述以及模拟实现

  • 从上述结果我们不难发现,经过验证程序是没有问题的。

 💨  接下来,我们在去看看在库中表现如何:

【C++】容器篇(一)—— vector 的基本概述以及模拟实现

 解释说明:

  1. erase删除pos位置元素后,pos位置之后的元素会往前搬移,没有导致底层空间的改变,理论上讲迭代 器不应该会失效;
  2. 但是:如果pos刚好是最后一个元素,删完之后pos刚好是end的位置,而end位置是 没有元素的,那么pos就失效了.因此删除vector中任意位置上元素时,vs就认为该位置迭代器失效 了。
  • 如果大家下去验证,发现不管是不是在结束的位置,编译器都会默认程序崩溃。

我们通过调试可以发现,库中默认的检查手段直接就是使得程序发送崩溃了:

【C++】容器篇(一)—— vector 的基本概述以及模拟实现

 注意:

  • 说明一点的是代码的结果还跟环境有关,大家可以去linux下进行测试看看结果是怎么样的

 💨  与vector类似,string在插入+扩容操作+erase之后,迭代器也会失效:

void TestString()
{
     string s("hello");
     auto it = s.begin();
     // 放开之后代码会崩溃,因为resize到20会string会进行扩容
     // 扩容之后,it指向之前旧空间已经被释放了,该迭代器就失效了
     // 后序打印时,再访问it指向的空间程序就会崩溃
     //s.resize(20, '!');
     while (it != s.end())
     {
         cout << *it;
         ++it;
     }
     cout << endl;
     it = s.begin();
     while (it != s.end())
     {
         it = s.erase(it);
         // 按照下面方式写,运行时程序会崩溃,因为erase(it)之后
         // it位置的迭代器就失效了
         // s.erase(it); 
         ++it;
     }
}

终上所述,我们认为在erase之后,pos是会发生失效的,因此建议不要访问,行为结果未定义(具体跟编译器有关系)


5️⃣swap()

        void swap(vector<T>&arr)
		{
			swap(_start, arr.start);
			swap(_end, arr.end);
			swap(_end_of_storage, arr._end_of_storage);
		}

总结

到此,关于vector的全部内容便讲解完毕了,接下来我们简单的总结一下本文都学了什么

  1. 首先,在开头我先给大家介绍了关于 STL库中的容器有哪些,让大家初步的认识了各个容器,对其有个基本的印象;
  2. 其次,先给出了关于vector的基本概念介绍,让大家知道vector的作用以及优势;
  3. 接下来,我们通过结合文档内容,带大家去认识了vector中最常用的接口并模拟实现了各个函数接口;
  4. 最后,关于vector最重要的便是关于迭代器失效的问题以及解决方法(重点)需要大家掌握。

以上全是全文的基本内容了。感谢大家的阅读与支持!!!

【C++】容器篇(一)—— vector 的基本概述以及模拟实现文章来源地址https://www.toymoban.com/news/detail-465424.html

到了这里,关于【C++】容器篇(一)—— vector 的基本概述以及模拟实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++ stl容器vector的底层模拟实现

    目录 前言:   1.成员变量,容量与大小 2.构造函数 无参构造: 带参的使用值进行构造:  使用迭代器区间进行构造: 3.交换 4.拷贝构造 5.赋值重载 6.迭代器 7.扩容 reserve: resize: 8.插入与删除 insert: erase: insert迭代器失效问题: erase迭代器失效问题: 9.头插头删 10.[]重载

    2024年04月15日
    浏览(42)
  • 【C++庖丁解牛】vector容器的简易模拟实现(C++实现)(最后附源码)

    🍁你好,我是 RO-BERRY 📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 我们前面介绍了vector容器的概念以及对其基本使用进行了介绍,如果你在这里不知道vector是什么以及不知

    2024年03月14日
    浏览(44)
  • C++:vector使用以及模拟实现

    和我们原来讲的string不同, vector并不是类,是一个类模板,加类型实例化以后才是类。 vector是表示 可变大小数组 的序列容器。 像数组一样 ,vector也采用的连续存储空间来存储元素,但是容量可以动态改变。 和其它容器相比,vector访问元素、尾插、尾删较高效,但不在尾部

    2024年02月11日
    浏览(43)
  • 【C++】:STL源码剖析之vector类容器的底层模拟实现

    构造一个空vector size和capacity为0 将_start _finish _endofstorage 都置为空指针即可 传统写法 : 1). 新开辟一块和 v 同样容量的空间,更新 _start, _finish, _endofstorage 2). 将 v 中的数据拷贝到新开辟的空间中 注意 : 不要使用memcpy函数拷贝数据,如果数据是内置类型或浅拷贝的自定义类型

    2024年02月04日
    浏览(52)
  • 【C++】反向迭代器的模拟实现通用(可运用于vector,string,list等模拟容器)

    🌏博客主页: 主页 🔖系列专栏: C++ ❤️感谢大家点赞👍收藏⭐评论✍️ 😍期待与大家一起进步! 我们要写出一个通用的反向迭代器模拟而且在保证代码简介不繁琐的的情况下,一定程度上使用我们自己模拟的已经封装好的iterator迭代器可以简化许多步骤,首先我们要知

    2024年02月14日
    浏览(55)
  • 【C++】-vector的模拟实现(以及memcpy如何使用)

    💖作者:小树苗渴望变成参天大树🎈 🎉作者宣言:认真写好每一篇博客💤 🎊作者gitee:gitee✨ 💞作者专栏:C语言,数据结构初阶,Linux,C++ 动态规划算法🎄 如 果 你 喜 欢 作 者 的 文 章 ,就 给 作 者 点 点 关 注 吧! 今天来带大家看看vector的模拟实现,思路来说还是比较简

    2024年02月17日
    浏览(41)
  • [C++历练之路]vector的介绍以及底层模拟实现

    W...Y的主页 😊 代码仓库分享 💕 🍔前言: 我们学习了STL中的string以及其所有重要接口并进行了模拟实现,但是STL中包含的内容不止于此。学习了string之后继续学习STL中的vector,学习成本会大大降低,因为他们非现类似,现在就让我们进入vector的世界中吧! 目录 vector的介绍

    2024年02月04日
    浏览(46)
  • 【C++进阶(二)】STL大法--vector的深度剖析以及模拟实现

    💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:C++从入门到精通⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习C++   🔝🔝 和string的学习不同 vector即要掌握它的用法 更要会自己去实现一个vector 本章重点: 熟悉STL库中vector的接口函数 自己实现一个简易vector类 本

    2024年02月11日
    浏览(38)
  • 【C++进阶(五)】STL大法--list模拟实现以及list和vector的对比

    💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:C++从入门到精通⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习C++   🔝🔝 本篇文章立足于上一篇文章: list深度剖析(上) 请先阅读完上一篇文章后再阅读这篇文章! 本章重点: 本章着重讲解list的模拟实现 list模拟实

    2024年02月09日
    浏览(53)
  • 【C++】vector容器初步模拟

    送给大家一句话: 努力一点,漂亮—点,阳光一点。早晚有一天,你会惊艳了时光,既无人能替,又光芒万丈。 今天我我来进行vector的模拟实现,先简单的实现一下初步功能,使其对内置类型可以适配。(大部分与string很类似) vector是表示 可变大小数组 的序列容器。 就像

    2024年04月08日
    浏览(87)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包