vector 笔记c++

#include<iostream>
#include<vector>//vector容器
#include<algorithm>//排序;头文件
#include<stdlib.h>
#include"myvector.h"

using namespace std;
/*
vector介绍:
1、写法:vector<类型>
2、vector是一个序列式容器,序列式容器是有顺序的数组。
3、vector的插入是一种剪切的形式;每次插入数据都是把之前的剪切,然后重新扩充一个空间插入数据。
4、每次扩充的方式比如:1 2 3 4 6 9 13 19;其中规律是:加前一个的一半;数字式表达如:6=4+4/2;
*/
void VectorTest()//vector测试
{
	vector<int> vec;//初始化一个数组vec
	int count = 0;//计算扩充次数
	for (int i = 0; i < 1000000; i++)
	{
		vec.push_back(0);//push_back():从头开始压数据
		int size = vec.size();//vec.size():获取数组大小
		int capacity = vec.capacity();//vec.capacity():获取数组最大数值
		//输出
		if (size == capacity)
		{
			cout << size << "\t" << capacity << endl;
			count++;
		}
	}
	cout << count << endl;
}

int main()
{

	//vector初始化方法:
	vector<int> vec1;       //初始化一个数组
	vector<int> vec2(7);    //声明一个初始化为7大小的数组
	vector<int> vec3(5, 2);  //声明一个初始化大小为5且数值都是2的数组
	vector<int> vec4(vec3); //拷贝vec3

	//比大小
	CMyVector<int> vec8(20,12);
	CMyVector<int> vec9(20,11);

	bool dayu1 = vec8 > (vec9);//ture(真)
	bool dayu2 = vec8 >= (vec9);//ture(真)
	bool dayu3 = vec8 < (vec9);//fales(假)
	bool dayu4 = vec8 <= (vec9);//fales(假)

	//vector初始化在已有数组的基础上操作方法:	
	cout << "vector初始化:";
	int arr[] = { 1, 2, 3, 4, 5 };
	for (auto i : arr)
	{
		cout << i << " ";
	}
	cout << endl << endl;
	vector<int> vec5(arr, arr + 5);//将arr到arr+5范围的元素作为vec5的初始化
	vector<int> vec6(&arr[0], &arr[4]);//将arr[1]--arr[4]范围的元素作为vec6的初始化,其中不包含arr[4];

	//vector末尾添加元素
	vec1.push_back(10);
	vec1.push_back(20);
	vec1.push_back(30);

	//vector删除末尾元素
	vec1.pop_back();

	//迭代器使用方法:
	cout << "迭代器的:";
	//开始迭代器 迭代开头的第一个;
	cout << *vec1.begin() << " ";

	//末尾迭代器 迭代结尾的最后一个;
	//end()指向最后一个元素的下一个位置;也就是在忘右边移动一个位置
	cout << *(vec1.end() - 1) << endl;
	cout << endl;
	//vector访问方法
	cout << "vector访问方法:";
	vec1[1] = 90;//下标访问 但是不检查越界。也就是有几率可以越界
	vec1.at(0) = 80;//at方法访问 检查是否越界 越界抛出out_of_range

	//const迭代器
	vec1.cbegin(), vec1.cend();//加一个c就是const,只读版本的begin和end;也就是不能修改的
	cout << vec1.front() << " ";//访问第一个元素,并不检查是否存在;
	cout << vec1.back() << endl;//访问最后一个元素,并不检查是否存在;

	int *p = vec1.data();//返回指针指向数组 只有支持c++11的才能用
	vec1.clear();//清空向量;可以理解为清空一切
	cout << endl;
	//vector遍历
	//压入
	for (int i = 0; i < 10; ++i)
	{
		vec1.push_back(i);
	}
	//输出
	cout << "遍历输出:";
	vector<int>::iterator it;//定义一个迭代器
	for (it = vec1.begin(); it != vec1.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl << endl;
	//测试
	cout << "元素个数:" << vec1.size() << endl << endl;

	cout << "翻转后:";
	reverse(vec1.begin(), vec1.end());//vec1.begin()+1就是第一个不用翻转,把之后的翻转
	for (auto i : vec1)
	{
		cout << i << " ";
	}
	cout << endl << endl;

	cout << "排序后:";
	sort(vec1.begin(), vec1.end());//排序关键词sort(开头,结尾),头文件为#include<algorithm>
	for (auto i : vec1)
	{
		cout << i << " ";
	}
	cout << endl << endl;

	//bool判断
	bool bEmpty = vec1.empty();//判断是否为空,不是空为:fales(假);是空为:true(真);

	//vector的存储量范围
	vec3.reserve(10);//设置储存量范围,只能增加。

	//vector的重新分配内存
	vec3.assign(3, 4);//assing是重新分配内存关键词

	VectorTest();//每次新增当前存储量的二分之一

	
	system("pause");
}

头文件include"MyVector.h"

#pragma once

template<typename T>
class CMyVector
{
	T* pBuff;//动态数组首地址
	size_t nSize;//动态数组大小
	size_t nCapacity;//动态数组最大长度
public:
	typedef T* iterator;//普通迭代器
	typedef const T* const_iterator;//常迭代器
public:
	iterator begin()
	{
		return pBuff;
	}
	iterator end()
	{
		return pBuff + nSize;
	}
	const_iterator cbegin()
	{
		return pBuff;
	}
	const_iterator cend()
	{
		return pBuff + nSize;
	}
public:
	//默认构造函数+单参构造函数
	explicit CMyVector(int n = 0);
	//拷贝构造
	CMyVector(CMyVector<T> const&);
	//重载一个双参构造函数
	CMyVector(int n,T const&);
	//clear清除数组
	void clear();
	//析构构造
	~CMyVector();
public:
	//重载 = == !=
	CMyVector<T>& operator =(CMyVector<T>const &that);
	bool operator == (CMyVector<T> const &srcVector)const;
	bool operator != (CMyVector<T> const &srcVector)const;
	//重载 > >= < <=
	bool operator > (CMyVector<T> const &srcVector)const;
	bool operator >= (CMyVector<T> const &srcVector)const;
	bool operator < (CMyVector<T> const &srcVector)const;
	bool operator <= (CMyVector<T> const &srcVector)const;
public:
	void assign(int n, T const&);//重新分配内存
	void swap(CMyVector<T>&);//数据交换
	friend void swap(CMyVector<T>& v1, CMyVector<T>& v2)//友元数据交换
	{
		v1.swap(v2);
	}
public:
	size_t size()const;//获取当前元素个数size
	size_t capacity()const;//获取最大capacity
	bool empty()const;//判断元素是否为空
	void reserve(int n);//重新分配最大内存
	void resize(int n);//重新分配nSize大小
	void resize(int n, T const &);//重载,重新分配nSize大小并赋值	
public:
	T& at(int index)const;//at方法访问 检查是否越界 越界抛出out_of_range
	T& operator[](int index)const;//重载[] 下标访问 不检查越界。也就是有几率可以越界
	T& front();//访问第一个元素,并不检查是否存在;
	T& back();//访问最后一个元素,并不检查是否存在;
public:
	void push_back(T const&);//末尾添加元素
	void pop_back();//末尾删除元素
};

template<typename T>
CMyVector<T>::CMyVector(int n) :nSize(n), nCapacity(n), pBuff(nullptr)
{
	pBuff = new T[nCapacity];//分配内存
	/*
	memset通常为新申请的内存进行初始化工作,它是直接操作内存空间。
	pBuff -- 指向要填充的内存块。
	0 -- 要被设置的值。该值以 int 形式传递,但是函数在填充内存块时是使用该值的无符号字符形式。
	sizeof(T)*nSize -- 要被设置为该值的字符数。
	*/
	memset(pBuff, 0, sizeof(T)*nSize);//可以不写,但是要考虑许多情况多一个更安全
}

template<typename T>
CMyVector<T>::CMyVector(CMyVector<T> const&that) :nSize(that), nCapacity(that), pBuff(nullptr)
{
	if (nCapacity)//判断最大长度是否为空
	{
		pBuff = new T[nCapacity];//分配空间
		memcpy(pBuff, that.pBuff, sizeof(T)*that.nSize);//拷贝复制
	}
}

template<typename T>
CMyVector<T>::CMyVector(int n, T const&elem) :nSize(n), nCapacity(n), pBuff(nullptr)
{
	pBuff = new T[nCapacity];//分配空间
	for (int i = 0; i < nSize; ++i)
	{
		pBuff[i] = elem;//循环赋值
	}
}

template<typename T>
void CMyVector<T>::clear()
{
	nSize = 0;//先清空大小
	if (pBuff)//然后判断数值是否为空
	{
		delete pBuff;//有数值就清空
	}
	pBuff = nullptr;//归零
}

template<typename T>
CMyVector<T>::~CMyVector()
{
	clear();//调用清空
}
//重载=
template<typename T>
CMyVector<T>& CMyVector<T>::operator=(CMyVector<T>const &that)
{
	if*(this != that)//先判断是否相等,避免重复赋值
	{
		// = 重载步骤为:先创造新内存,然后释放旧内存;
		T* p_tmp = new T[that.nCapacity];//分配新内存
		memcpy(p_tmp, that.pBuff, sizeof(T)*that.nSize);//拷贝新资源
		clear();//释放旧资源
		//把复制的临时资源到新的内存中
		this->pBuff = p_tmp;
		this->nSize = that.nSize;
		this->nCapacity = that.nCapacity;
	}
	return *this;//返回自己
}
//重载==
template<typename T>
bool CMyVector<T>::operator == (CMyVector<T> const &srcVector)const//可以参考strcmp
{
	if (nSize != srcVector.nSize)
	{
		return false;
	}
	for (int i = 0; i < nSize; ++i)
	{
		if (pBuff[i] != srcVector.pBuff[i])
			return false;
	}
	return true;
}

template<typename T>
bool CMyVector<T>::operator != (CMyVector<T> const &srcVector)const
{
	return !(this == srcVector);
}

template<typename T>
bool  CMyVector<T>::operator > (CMyVector<T> const &srcVector)const
{
	for (int i = 0; i < nSize; ++i)
	{
		if (pBuff[i] > srcVector.pBuff[i] || pBuff[i] == srcVector.pBuff[i])
			return true;
	}
	return false;
}

template<typename T>
bool CMyVector<T>::operator < (CMyVector<T> const &srcVector)const
{
	for (int i = 0; i < nSize; ++i)
	{
		if (pBuff[i] < srcVector.pBuff[i] || pBuff[i] == srcVector.pBuff[i])
			return true;
	}
	return false;
}

template<typename T>
bool CMyVector<T>::operator >= (CMyVector<T> const &srcVector)const
{
	for (int i = 0; i < nSize; ++i)
	{
		if (pBuff[i] > srcVector.pBuff[i] || pBuff[i] == srcVector.pBuff[i])
			return true;
	}
	return false;
}

template<typename T>
bool CMyVector<T>::operator <= (CMyVector<T> const &srcVector)const
{
	for (int i = 0; i < nSize; ++i)
	{
		if (pBuff[i] < srcVector.pBuff[i] || pBuff[i] == srcVector.pBuff[i])
			return true;
	}
	return false;
}

template<typename T>
void CMyVector<T>::assign(int n, T const&elem)
{
	clear();//先清空数据
	//判断n是否大于Capacity,并且是否小于size
	if (n > nCapacity&&n < nSize)
	{
		nSize = nCapacity = n;//赋值
	}

	pBuff = new T[nCapacity];//开辟一个空间
	//依次赋值
	for (int i = 0; i < n; ++i)
	{
		pBuff[i] = elem;
	}
}

template<typename T>
void CMyVector<T>::swap(CMyVector<T>& srcVector)
{
	CMyVector temp;//创建临时变量储存数据
    //交换储存数据
	temp = *this;
	*this = srcVector;
	srcVector = temp;
}

template<typename T>
size_t CMyVector<T>::size()const
{
	return nSize;
}

template<typename T>
size_t CMyVector<T>::capacity()const
{
	return nCapacity;
}

template<typename T>
bool CMyVector<T>::empty()const
{
	return nSize == 0;
}

//扩大内存的原理是:
/*
  1、要把旧的(pBuff)先赋值到(tempBuff)一个新开的空间,
  2、然后清空(pBuff)。
  3、在把(tempBuff)中的数据赋值给(pBuff)(nCapacity),
*/
template<typename T>
void CMyVector<T>::reserve(int n)//n为最大内存空间
{
    if (n > nSize)
	{
		T* tempBuff = new T[n];//先开辟一个空间
		memcpy(tempBuff, pBuff, sizeof(T)*nSize);//吧pBuff复制到tempBuff存储
		if (pBuff)//判断是否为空,不为空就delete
		{
			delete pBuff;
		}
		pBuff = tempBuff;
		nCapacity = n;
	}
}

//缩小、扩大nSize
template<typename T>
void CMyVector<T>::resize(int n)
{
	if (n > nSize)//判断是否大于nSize,执行扩大操作
	{
		reserve(n);
		/*memset:将缓冲区设置为指定的字符。
		  &pBuff[nSize]指向目标的指针。0要设置的字符。sizeof(T)*(n - nSize)要操作的字符数。
		*/
		memset(&pBuff[nSize], 0, sizeof(T)*(n - nSize));
	}
	/*
	  其中原理是:
	  缩小nSize访问元素的权限,其操作可逆,
	  注释:缩小的是访问权限,数据还在。
	*/
	if (n < nSize)//判断是否小于nSize,执行缩小操作
	{
		nSize = n;
	}
}

template<typename T>
void CMyVector<T>::resize(int n, T const&elem)
{
	resize(n);
	for (size_t i = nSize; i < n; ++i)
	{
		pBuff[i] = elem;
	}
}

template<typename T>
T& CMyVector<T>::at(int index)const
{
	if (index >= 0 && index < nSize)//判断index是否大于0并且小于nSize
	{
		return pBuff[index];
	}
	throw std::out_of_range("越界");
}

template<typename T>
T& CMyVector<T>::operator[](int index)const
{
	return pBuff[index];
}

template<typename T>
T& CMyVector<T>::front()
{
	return pBuff[0];
}

template<typename T>
T& CMyVector<T>::back()
{
	//注释:nSize不是下标;不是从0开始计算,是从1开始计算的。所以要-1;
	//pBuff[nSize-1]这样才为下标;
	return pBuff[nSize-1];
}

template<typename T>
void CMyVector<T>::push_back(T const&elem)
{
	if (nSize == nCapacity)
	{
		return (2 * nCapacity + 1);//算法1
	}
	pBuff[nSize++] = elem;
}

template<typename T>
void CMyVector<T>::pop_back()
{
	if (nSize > 0)
	{
		nSize--;
	}
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柳一航

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值