首页 > 其他分享 >22String字符串和vector对象的迭代器iterator实现

22String字符串和vector对象的迭代器iterator实现

时间:2024-01-20 23:34:51浏览次数:26  
标签:last iterator 22String vector return first allocator size

String字符串对象的迭代器iterator实现

  • 泛型算法参数接收的都是迭代器
  • 泛型算法是一组全局的函数,适用于所有容器
  • 基于第二点,泛型算法有一套方法可以统一地遍历所有容器的元素
class String
{
public:
	//嵌套定义iterator类
	class iterator
	{
	private:
		char* _p; //没有用到外部资源,无需拷贝构造函数
	public:
		iterator(char *p):_p(p){}
		char operator*() const
		{
			return *(this->_p);
		}
		bool operator!=(const iterator& it) const
		{
			return _p != it._p;
		}
		void operator++()
		{
			++_p;
		}
	};
private:
	char* _pstr;
	...
}

vector对象的迭代器iterator实现

#include<iostream>

using namespace std;

// 容器的空间配置器allocator做四件事情  内存开辟/内存释放  对象构造/对象析构
template<typename T>
struct Allocator
{
	T* allocate(size_t size) // 负责内存开辟
	{
		return (T*)malloc(sizeof(T) * size);
	}
	void deallocate(void* p) // 负责内存释放
	{
		free(p);
	}
	void construct(T* p, const T& val) // 负责对象构造
	{
		new (p) T(val); // 定位new
	}
	void destroy(T* p) // 负责对象析构
	{
		p->~T();
	}
};

/*
容器底层内存开辟,内存释放,对象构造和析构,都通过allocator空间配置器来实现
*/
template<typename T, typename Alloc = Allocator<T>>
class vector
{
public:
	vector(int size = 10)
	{
		// 需要把内存开辟和对象构造分开处理
		// _first = new T[size];
		_first = _allocator.allocate(size);
		_last = _first;
		_end = _first + size;
		cout << "vector()" << endl;
	}
	~vector()
	{
		// 析构容器有效的元素,然后释放_first指针指向的堆内存
		// delete[] _first;
		for (T* p = _first; p != _last; ++p) // 把有效的对象析构从_first到_last
		{
			_allocator.destroy(p);
		}
		_allocator.deallocate(_first); // 释放内存
		_first = _end = _last = nullptr;
	}
	vector(const vector<T>& rhs)
	{
		int size = rhs._end - rhs._first;
		//_first = new T[size];
		_first = _allocator.allocate(size);
		int len = rhs._last - rhs._first;
		for (int i = 0; i < len; ++i)
		{
			//_first[i] = rhs._first[i];
			_allocator.construct(_first + i, rhs._first[i]);
		}
		_last = _first + len;
		_end = _first + size;
	}
	vector<T>& operator = (const vector<T>& rhs)
	{
		if (this == &rhs)
		{
			return *this;
		}

		//delete[] _first;
		for (T* p = _first; p != _last; ++p) // 把有效的对象析构从_first到_last
		{
			_allocator.destroy(p);
		}
		_allocator.deallocate(_first);

		int size = rhs._end - rhs._first;
		//_first = new T[size];
		_first = _allocator.allocate(size);
		int len = rhs._last - rhs._first;
		for (int i = 0; i < len; ++i)
		{
			//_first[i] = rhs._first[i];
			_allocator.construct(_first + i, rhs._first[i]);
		}
		_last = _first + len;
		_end = _first + size;
		return *this;
	}
	void push_back(const T& val)
	{
		if (full())
			expand();
		//*_last++ = val;  _last指针指向的内存构造一个值为val的对象
		_allocator.construct(_last, val);
		_last++;
	}
	void pop_back()
	{
		if (empty())
			return;
		//--_last;   不仅要把_last指针--,还需要析构删除的元素
		--_last;
		_allocator.destroy(_last);
	}
	T back() const
	{
		return *(_last - 1);
	}
	bool full() const { return _last == _end; }
	bool empty() const { return _first == _last; }
	int size() const { return _last - _first; }
	T& operator[] (int index)
	{
		if (index < 0 || index >= size())
		{
			throw "OutOfRangeException";
		}
		return _first[index];
	}
	class iterator
	{
	public:
		iterator(T* p = nullptr) :_p(p) {}
		bool operator!=(const iterator& it) const
		{
			return _p != it._p;
		}
		void operator++()
		{
			++_p;
		}
		T& operator*() { return *_p; }
		const T& operator*() const{ return *_p; }
	private:
		T* _p;
	};

	iterator begin() { return iterator(_first); }
	iterator end() { return iterator(_last); }
private:
	T* _first;
	T* _last;
	T* _end;
	Alloc _allocator;
	void expand()
	{
		int size = _end - _first;
		//T* ptmp = new T[2 * size];
		T* ptmp = _allocator.allocate(2 * size);
		for (int i = 0; i < size; i++)
		{
			_allocator.construct(ptmp + i, _first[i]);
			//ptmp[i] = _first[i];
		}
		//delete[] _first;
		for (T* p = _first; p != _last; ++p)
		{
			_allocator.destroy(p);
		}
		_allocator.deallocate(_first);
		_first = ptmp;
		_last = _first + size;
		_end = _first + 2 * size;
	}
};

class Test
{
public:
	Test() { cout << "Test()" << endl; }
	~Test() { cout << "~Test()" << endl; }
	Test(const Test&) { cout << "Test(const Test&)" << endl; }
};

int main()
{
	vector<int> vec;
	for (int i = 0; i < 20; i++)
	{
		vec.push_back(rand() % 100 + 1);
	}
	for (int i = 0; i < 20; i++)
	{
		//底层数据结构不连续时不支持中括号重载
		cout << vec[i] << endl;
	}
	auto it = vec.begin();
	for (; it != vec.end(); ++it)
	{
		cout << *it << endl;
	}
}

标签:last,iterator,22String,vector,return,first,allocator,size
From: https://www.cnblogs.com/sio2zyh/p/17977363

相关文章

  • SciTech-Math-AdvancedAlgebra-Linear Spaces(Vector Spaces) and Subspace: The Colu
    https://math.mit.edu/~gs/dela/dela_5-1.pdfhttps://people.math.harvard.edu/~knill/teaching/math22b2019/handouts/lecture01.pdfhttps://web.stanford.edu/group/dabmgroup/cgi-bin/dabm/wp-content/uploads/2021/12/Lecture_14.pdfN-elementorderedNumberSequence......
  • C++ vector和set排序效率比较
    转自:https://blog.csdn.net/adaptiver/article/details/529257921.介绍vector+sort实际是快排,快速排序是目前已知的所有排序算法中最快的排序算法。例子:#include<vector>#include<set>#include<algorithm>#include<stdio.h>#include<string.h>#include<unistd......
  • STL vector用法
    STLvector变长数组倍增的思想(系统为某一程序分配空间时,所需时间与空间大小无关,与申请请求次数有关)size() empty() clear()清空front()/back() push_back()/pop_back() begin()/end() []支持比较运算#include<iostream>#include<cstring>#include<cstdio>#i......
  • 通过模板类实现一个简单的vector容器
    什么是模板模板分为类模板和函数模板,关键字为template,基本的声明形式如下:template<classT>;//也可以写成这样template<typenameT>class和typename在声明模板参数时的用法是相似的,一般情况下可以互换但在成员模板内部访问嵌套类型时,需要使用typename。下面举一个例子加以理......
  • C++STL常用容器vector以及常用接口
    2.0vector容器2.1.1vector基本概念功能:vector数据结构和数组非常相似,也称为矢量,向量vector与普通数组区别:不同之处在于数组是静态空间,而vector可以动态扩展动态扩展:并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝新空间,释放原空间vector容器的迭代器是支持随......
  • 基于源码去理解Iterator迭代器的Fail-Fast与Fail-Safe机制
    原创/朱季谦在Java编程当中,Iterator迭代器是一种用于遍历如List、Set、Map等集合的工具。这类集合部分存在线程安全的问题,例如ArrayList,若在多线程环境下,迭代遍历过程中存在其他线程对这类集合进行修改的话,就可能导致不一致或者修改异常问题,因此,针对这种情况,迭代器提供了两种处......
  • 【Cpp 语言基础】vector像数组一样地初始化多个元素
    一般的vector的初始化有两种方式,push_back和(n,val)方式vector<int>vect;//一般方式vect.push_back(10);vect.push_back(20);//Createavectorofsizenwith//allvaluesas10.vector<int>vect(n,10);但是也可以像C语言的数组一样初始化://方式3:直接像数组一......
  • MSI VECTOR GP78 HX 13V笔记本电脑安装win11的坑
    MSIVECTORGP78HX13V笔记本电脑在启动系统安装导引程序后,没办法查看磁盘驱动器,其原因是开启了BIOS系统中的VolumeManagementDevice(VMD)。VMD是针对INTEL10代处理器之后PC的,简单来讲是新一代存储部署方案,支持从PCIe总线对NVMe固态盘进行热升级和更换。为了在安装win11系统时正......
  • 【STL】 vector
    #include<vector>连续的顺序的储存结构(和数组一样的类别),但是有长度可变的特性。构造vector<类型>arr(长度,[初值])时间复杂度:O(n)常用的一维和二维数组构造示例,高维也是一样的(就是会有点长)。vector<int>arr;//构造int数组vector<int>arr(100);//构造初......
  • Derivative norm vector repect to time 《PBM by Pixar》 Appendix D.2 code
    目录1Derivativenormalvectorrepecttotime1.1DerivativevectornormrepecttotimeXRefVectorCalculus1DerivativenormalvectorrepecttotimeLet'sdenotetheunitnormalvectoras:\[\mathbf{n}=\frac{\mathbf{e}_a\times\mathbf{e}_b}{......