vector

底层:
          动态数组/缓冲区列表,元素按照插入的顺序依次存储在内存中



特点:
          1、连续存储:内部内存块连续,元素连续存放
          2、动态增长:如果当前容量不足,重新申请一块更大的内存(一般为当前容量的2倍),并将元素赋值到新的内存中
          3、快速随机访问:支持通过下标快速访问任何位置的元素
          4、动态大小调整:大小可动态调整,可在运行时轻松添加和删除元素
          5、迭代器支持:提供了迭代器用于遍历容器中元素,包括正向迭代器和反向迭代器
          6、元素访问成本:通过索引访问元素的成本很低,只需要进行简单的地址计算
          适合快速随机访问和动态增长



缺点:
          1、插入和删除开销大:可能会导致后续元素移动,时间复杂度为o(n)
          2、动态增长可能导致重新分配:容量不足时,需要重新申请内存块,导致性能开销
          3、不适合频繁插入删除操作:插入和删除开销大,所以不适合
          4、固定大小的元素类型:所有元素的类型必须相同,不支持存储不同类型的元素
          5、指定预留空间:如果事先不能确定元素数量的上限,可能需要预留较大空间,导致资源浪费


成员方法:

          1、构造函数和析构函数
          2、operator= 赋值操作符重载
          3、push_back() - 在末尾添加元素
          4、pop_back() - 删除末尾元素
          5、size() - 返回元素数量
          6、capacity() - 返回容量
          7、resize() - 更改大小
          8、empty() - 检查是否为空
          9、clear() - 清空所有元素
          10、begin() - 返回指向起始位置的迭代器
          11、end() - 返回指向结束位置的迭代器
          12、front() - 返回第一个元素的引用
          13、back() - 返回最后一个元素的引用
          14、at() - 返回指定位置元素的引用,并进行越界检查
          15、insert() - 在指定位置插入元素
          16、erase() - 删除指定位置或范围的元素
          17、swap() - 交换两个vector的内容
          18、emplace() - 在指定位置构造元素
          19、emplace_back() - 在末尾构造元素


类部分成员简单自定义(无迭代器):

#include<iostream>
#include <stdexcept>
template<class T>
class  _Vector
{
private:
	T* arr;
	size_t capacity;
	size_t size;
public:
	//构造、析构
	_Vector() : capacity(10),size(0)
	{
		arr = new T[capacity];
	}
	_Vector(size_t _size):capacity(_size),size(_size)
	{
		arr = new T[capacity]();
	}
	_Vector(const _Vector& _vector) :capacity(_vector.capacity), size(_vector.size)
	{
		arr = new T[capacity];
		for (size_t idx = 0; idx < size; idx++) {
			arr[idx] = _vector.arr[idx];
		}
	}
	/*
		移动构造:
			从一个临时对象或即将销毁的对象"窃取"资源,而不是像拷贝构造函数一样创建新的资源副本,可避免不必要的资源拷贝开销,提高性能和效率
			noexcept表示该构造函数不会抛出异常
	*/
	_Vector(_Vector&& _vector)noexcept :arr(_vector.arr),capacity(_vector.capacity), size(_vector.size)
	{
		_vector.arr = nullptr;
		_vector.capacity = 0;
		_vector.size = 0;
	}
	~_Vector()
	{
		delete[] arr;
	}
	T& operator[](size_t index)
	{
		if (index >= size)
		{
			throw std::out_of_range("index out of range");
		}
		return arr[index];
	}
	_Vector& operator =(const _Vector& _vector)
	{
		/*
			防止自我赋值:
				-> _vector = _vector;
				1、赋值时首先会调用赋值操作符函数
				2、删除当前对象中的数组arr
				3、尝试拷贝自身的元素到重新分配的内存中,但由于此时arr被删除,会导致内存无法访问
				-> 程序出现未定义行为,可能导致崩溃,内存泄漏等情况
		*/
		if (this != _vector) 
		{
			delete[] arr;
			capacity = _vector.capacity;
			size = _vector.size;
			arr = new T[capacity]();
			for (size_t idx = 0; idx < size; idx++)
			{
				arr[idx] = _vector[idx];
			}
		}
		return *this;
	}
	size_t getSize()const
	{
		return size;
	}
	size_t getCap()const 
	{
		return capacity;
	}
	T& at(size_t index)
	{
		if (index >= size)
		{
			throw std::out_of_range("index out of range");
		}
		return arr[index];
	}
	bool isEmpty()const 
	{
		return size == 0;
	}
	void clear()
	{
		size = 0;
	}
	void push_back(const T& inVal)
	{
		if (capacity == size)
		{
			reserve(capacity * 2);
		}
		arr[getSize()] = inVal;
	}
	void pop_back()
	{
		if (size > 0) {
			size--;
		}
	}
	void reserve(size_t _capacity)
	{
		if (_capacity <= capacity) {
			return;
		}
		T* _arr = new T[_capacity];
		for (size_t _size = 0; _size < size; _size++) {
			_arr[_size] = arr[_size];
		}
		delete[] arr;
		arr = _arr;
		capacity = _capacity;
	}
	T& front()const 
	{
		if (isEmpty()) {
			throw std::out_of_range("vector is empty");
		}
		return arr[0]; 
	}
	T& back()const 
	{
		if (isEmpty()) {
			throw std::out_of_range("vector is empty");
		}
		return arr[size - 1];
	}
	void resize(size_t _size, T val = T())
	{
		if (_size < size) {
			size = _size
		}
		else if (_size > size){
			reserve(_size);
			for (size_t outSize = size; outSize < _size; outSize++) {
				arr[outSize] = val;
			}
			size = _size;
		}
	}
	
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值