数据结构与算法_重制vector

本文探讨了在不需要接口函数时使用结构体模拟动态数组的方法,并对比了自定义动态数组与系统vector在元素删除时的不同,指出系统vector删除可能导致内存重分配。文章强调在涉及动态内存时考虑拷贝构造函数,介绍了自定义at函数的作用,并分享了内存重分配的高效策略。此外,还提及析构函数的责任是释放堆内存和栈区内容,以及自定义清除函数的功能。附带代码实例供读者参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说明

  • 在结构体里面不需要定义接口函数时(不包括重载运算函数),(可以)用结构来模仿实现方式
  • 自己模拟的动态数组在元素删除是不会有内存重分配,但是系统vector在删除是会导致内存重分配
  • 在容器中找到一个对象不适用下标,也不使用指针,而是通过迭代器
  • 如果有动态内存的存在,要考虑拷贝构造的存在
  • 自定义at函数 是唯一个可以进行抛出异常的函数
  • 如果涉及到内存重分配,那么就要涉及到新申请一个足够大的新内存 内存重分配所用效率最高的分配方式-maxSize = maxSize +
    (maxSize >> 1) > 1 ? (maxSize >> 1) : 1)
  • 析构函数不仅会释放所申请堆内存,而且还会释放掉栈区内容
  • 自定义的清除函数会清除使用完成之后的堆区内存,但是MyVector内三个变量是存在的
  • 另外vector常见操作请见vector操作

代码实例

.cpp主函数文件

#include<iostream>
#include<vector>
#include"MyVector.h"
using namespace std;
int main()
{	
	vector<int> v;
 	for (int i = 0; i < 10; ++i) v.push_back(i + 1);
 	vector<int>::iterator vit;
 	for (vit = v.begin(); vit != v.end(); ++vit) printf("%d  ",*vit);
 	printf("\n");
 	CMyVector<int> v1;
 	for (int i = 0; i < 10; ++i) v1.push_back(i + 1);
 	CMyVector<int>::MyIterator vit1;
 	for (vit1 = v1.begin(); vit1 != v1.end(); ++vit1) printf("%d  ", *vit1);
 	cin.get();
 	return 0;
}

.cpp MyVector文件

//请注意,一级警报,类模板内的函数要在.h里实现!!!!!!!

.h文件

#pragma once
template<typename T>
class CMyVector
{
 	T *pBuff;
 	unsigned int len;
 	unsigned int maxSize;
public:
     struct MyIterator
     {
  		T *pIt;
  	MyIterator & operator=(MyIterator const& srcIt)
  	{
  	 	pIt = srcIt.pIt;
   		return *this;
  	}
 	 bool operator!=(MyIterator const& srcIt)
  	{
   		return pIt != srcIt.pIt;
  	}
  	MyIterator &operator++()//前置
  	{
   		pIt++;
   		return *this;
  	}
  	MyIterator &operator++(int)//后加加,先输出以前的值,然后在计算
  	{
   		MyIterator tempIt = *this;
   		pIt++;
   	return tempIt;
  	}
  	T &operator*()
  	{
   	return *pIt;
  	}
     };
public:
 	MyIterator begin()//得到容器的第一个位置
 	{
  		MyIterator tempIt;
  		tempIt.pIt = pBuff;
  		return tempIt;
 	}
 	MyIterator end()//得到容器的最后一个元素的下一个位置
 	{
  		MyIterator tempIt;
  		tempIt.pIt = pBuff + (len - 1) + 1;
  		return tempIt;
 	}
 	MyIterator operator-(MyIterator const& srcIt)const
 	{
  		return pIt-src.pIt;
 	}
 	MyIterator operator+(int n)
 	{
  		MyIterator tempIt = *this;
  		tempIt.pit += n;
  		return tempIt;
 	}
public:
 	MyIterator insert(MyIterator const& pos, MyIterator const& first, MyIterator const& second)
 	{
  		MyIterator tempIt = pos;
  		unsigned int n = second - first;
  		for (int i = 0; i < n; ++i)tempIt = insert(tempIt, *(first+i));
  		return tempIt;
 	}
 	MyIterator insert(MyIterator const& pos, int n, T const& elem)
 	{
 		 MyIterator tempIt = pos;
  		for (int i = 0; i < n; ++i)tempIt = insert(tempIt, elem);
  		return tempIt;
 	}
 	MyIterator insert(MyIterator const& pos, T const& elem)//插入函数,在pos这个迭代器所指的位置插入一个elem元素
 	{
  		int index = pos.pIt - pBuff;//通过迭代器位置和容器的首地址进行相减,得到当前下标
  		if (len >= maxSize)
  		{
   			maxSize = maxSize + ((maxSize >> 1) > 1 ? (maxSize >> 1) : 1);
   			T *tempBuff = new T[maxSize];
   		for (unsigned int i = 0; i < len; ++i) tempBuff[i] = pBuff[i];
   		if (pBuff != nullptr)delete[] pBuff;
   		pBuff = tempBuff;
 		}
  		//移动位置
  		for (unsigned int i = len; i > index; --i) pBuff[i] = pBuff[i - 1];
  		pBuff[index] = elem;
  		len++;
  		MyIterator tempIt;
  		tempIt.pIt = pBuff + index;
  		return tempIt;
 	}
 	//注意:自己模拟的动态数组在元素删除是不会有内存重分配,但是系统vector在删除是会导致内存重分配
	 void erase(MyIterator const& pos)
 	{
  		int index = pos.pIt - pBuff;
  		for (unsigned i = index; i < len - 1; ++i)
  		{
   			pBuff[i] = pBuff[i - 1];
  		}
  		len--;
 		 //内存位置更改的这步,自己模拟的时候是做不到的,只有机器底层才能拿到这个权限
  		MyIterator tempIt;
 		tempIt.pIt = pBuff + index;
  		return tempIt;
 	}
 	MyIterator erase(MyIterator const& first, MyIterator const& second)
 	{
  		int n = first - second;
  		MyIterator tempIt = first;
  		for (int i = 0; i < n; ++i)tempIt = erase(tempIt);
  		return tempIt;
 	}
public:
 	CMyVector();
 	CMyVector(int n);//有n个用T的默认构造构造的对象,构造进这个容器(就是说在使用的时候直接用这个构造,会构造n个默认类,只不过这个类的类型是T类型)——用来穿件对象数组
 	CMyVector(int n, T const& elem);//用n个elem对象构造进这个容器
 	CMyVector(CMyVector const& other);//如果有动态内存的存在,要考虑拷贝构造的存在
 	~CMyVector();//析构函数不仅会释放所申请堆内存,而且还会释放掉栈区内容
 	void clear();//清除使用完成之后的堆区内存,但是MyVector内三个变量是存在的
public:
 	unsigned int size() const;//用来检查对象里的len的值
 	unsigned int capacity() const;//判断容器大小
 	bool empty() const;//判断容器是否为空
public:
 	bool operator==(CMyVector const& srcVector)const;
 	bool operator!=(CMyVector const& srcVector)const;
 	//作业内容的五个函数
 	bool operator>(CMyVector const& srcVector)const;
 	bool operator>=(CMyVector const& srcVector)const;
 	bool operator<(CMyVector const& srcVector)const;
 	bool operator<=(CMyVector const& srcVector)const;
 	//friend void swap(CMyVector &srcVector, CMyVector &srcVector1);
public:
 	void assign(int n, T const& elem);//赋值,与构造函数赋值的区别在于,存在值之后重新赋值
 	void swap(CMyVector & srcVector);//交换
public:
 	T at(int index);//返回动态数组中下标为index的元素
 	T operator[](int index);//返回动态数组中下标为index的元素
 	T front();//得到容器中的第一个元素
 	T back();//得到容器中的最后一个元素
public:
 	void push_back(T const& elem);//往动态数组尾部进行添加数据
 	void pop_back();//从动态数组的尾部进行产出数据
public:
 	void resize(int num);//将元素的数量len改为num,如果size变大了将调用默认构造来创建
 	void resize(int num, T const& elem);
 	void reserve(int num);//如果容器容量不足,则扩大容量,但是不会使容器变小
};
template<typename T>
CMyVector<T>::CMyVector()
{
 	pBuff = nullptr;
 	len = 0;
 	maxSize = 0;
}
template<typename T>
CMyVector<T>::~CMyVector()
{
 	clear();
}
template<typename T>
void CMyVector<T>::clear()
{
 	if (pBuff != nullptr)
 	{
  		delete[] pBuff;
  		pBuff = nullptr;
  		len = 0;
  		maxSize = 0;
 	}
}
template <typename T>
CMyVector<T>::CMyVector(int n)
{
 	if (n <= 0)
 	{
  		pBuff = nullptr;
  		len = 0;
  		maxSize = 0;
 	}
 	else
 	{
  		len = maxSize = n;
  		pBuff = new T[maxSize];//用n构造出来的具有n个T类型的构造,具体实现
 	}
}
template<typename T>
CMyVector<T>::CMyVector(int n, T const& elem)
{
 	if (n <= 0)
 	{
  		pBuff = nullptr;
  		len = 0;
  		maxSize = 0;
 	}
 	else
 	{
  	len = maxSize = n;
  	//申请一个动态数组
  	pBuff = new T[maxSize];//用n构造出来的具有n个T类型的构造,具体实现
  	for (unsigned i = 0; i < len; ++i)
  		{
   			pBuff[i] = elem;//将元素elem压入到指针堆内存中
  		}
 	}
}
template<typename T>
CMyVector<T>::CMyVector(CMyVector const& other)
{
 	len = other.len;
 	maxSize = other.maxSize;
 	pBuff = nullptr;
 	if (len > 0)
 	{
  		pBuff = new T[maxSize];
  		for (int i = 0; i < len; ++i)
  		{
   		pBuff[i] = other.pBuff[i];
  		}
 	}
}
template<typename T>
unsigned int CMyVector<T>::size() const
{
	 return len;
}
template<typename T>
unsigned int CMyVector<T>::capacity() const
{
 	return maxSize;
}
template<typename T>
bool CMyVector<T>::empty()const
{
 	return len = 0;
}
template<typename T>
bool CMyVector<T>::operator==(CMyVector const& srcVector)const
{
 	if (len != srcVector.len)
  	return false;
 	for (size_t i = 0; i < len; ++i)
 	{
  		if (pBuff[i] != srcVector.pBuff[i])
   		return false;
 	}
 	return true;
}
template<typename T>
bool CMyVector<T>::operator!=(CMyVector const& srcVector)const
{
 	return !(*this == srcVector);//骚操作呦
}
template<typename T>
bool CMyVector<T>::operator>(CMyVector const& srcVector)const
{
 	unsigned int minLen = len < srcVector.len ? len : srcVector.len;
 	for (unsigned int i = 0; i < minlen; ++i)
 	{
 		 if (pBuff[i] > srcVector.pBuff[i])return true;
  		if (pBuff[i] < srcVector.pBuff[i])return false;
 	}
 	if (minlen == len)return false;
 	return true;
}
template<typename T>
bool CMyVector<T>::operator>=(CMyVector const& srcVector)const
{
	if (len > 0 && srcVector.len > 0)
 	{
  		for (int i = 0; i < len; ++i)
  		{
   			if (pBuff[i] < srcVector.pBuff[i]) return false;
  		}
  		return true;
 	}
}
template<typename T>
bool CMyVector<T>::operator<(CMyVector const& srcVector)const
{
 	if (!(*this > srcVector&&*this >= srcVector))return true;
 	else return false;
}
template<typename T>
bool CMyVector<T>::operator<=(CMyVector const& srcVector)const
{
 	if (len > 0 && srcVector.len > 0)
 	{
  		for (int i = 0; i < len; ++i)
  		{
   			if (pBuff[i] > srcVector.pBuff[i]) return false;
  		}
  		return true;
 	}
}
template<typename T>
void CMyVector<T>::assign(int n, T const& elem)
{
 	clear();
 	if (n > 0)
 	{
  		len = maxSize = n;
  		pBuff = new T[maxSize];
  		for (unsigned int i = 0; i < len; ++i)
  		{
   			pBuff[i] = elem;
  		}
 	}
 	for (int i = 0; i < len; ++i)
 	{
  		pBuff[i]
 	}
}
template<typename T>
void CMyVector<T>::swap(CMyVector & srcVector)
{
 	//定义临时变量
 	int tempLen, tempMaxSize;
 	T *tempPBuff;
	 //变量临时存放
 	tempLen = len;
 	tempMaxSize = maxSize;
 	tempPBuff = pBuff;
 	//第一次交换
 	len = srcVector.len;
 	maxSize = srcVector.maxSize;
 	pBuff = srcVector.pBuff;
 	//第二次交换
 	srcVector.len = tempLen;
 	srcVector.maxSize = tempMaxSize;
 	srcVector.pBuff = tempPBuff;
}
template<typename T>
T CMyVector<T>::at(int index)
{
 	if (len >= index&&index > 0) return pBuff[index];
 	else throw "out_of_range";
}
template<typename T>
T CMyVector<T>::operator[](int index)
{
 	return pBuff[index];
 	//if (len >= index&&index > 0) 
 	//else throw "out_of_range";vector内唯一的、只有at函数具有抛出异常的特点,其它函数不具有
}
template<typename T>
T CMyVector<T>::front()
{
 	return pBuff[0];
}
template<typename T>
T CMyVector<T>::back()
{
 	return pBuff[len - 1];
}
template<typename T>
void CMyVector<T>::push_back(T const& elem)
{
 //1 2 3 4 6 9 13 19
 	if (len >= maxSize)
 	{
 	 	maxSize = maxSize + ((maxSize >> 1) > 1 ? (maxSize >> 1) : 1);
  		T *tempBuff = new T[maxSize];
  		for (size_t i = 0; i < len; ++i)
   		tempBuff[i] = pBuff[i];
  		if (pBuff != nullptr)
   		delete[] pBuff;
  		pBuff = tempBuff;
 	}
 	pBuff[len++] = elem;
}
template<typename T>
void CMyVector<T>::pop_back()
{
 	--len;//对于可能存在的len=-1的情况,需要使用类模板的程序员员在前面用给出的其它成员函数进行判断
}
template<typename T>
void CMyVector<T>::resize(int num)
{
 	if (num < 0)assert(nullptr);//assert 断言函数----相当于打断点报错
        //if(len == num)return;
        //if (len > num)len = num;
 	if (len < num)
 	{
  	while (num >= maxSize)
  	{
  		 maxSize = maxSize + ((maxSize >> 1) > 1 ? (maxSize >> 1) : 1);
  	}
  	T *tempBuff = new T[maxSize];
  	for (size_t i = 0; l < len; ++i)
  	{
   		tempBuff[i] = pBuff[i];
  	}
  	if (pBuff != nullptr)delete[] pBuff;
 	pBuff = tempBuff;
 }
 	len = num;
}
template<typename T>
void CMyVector<T>::resize(int num, T const& elem)
{
 	if (num < 0)assert(nullptr);//assert 断言函数----相当于打断点报错
        //if(len == num)return;
        //if (len > num)len = num;
 	if (num>len)
 	{
  		while (num >= maxSize)
   		maxSize = maxSize + ((maxSize >> 1) > 1 ? (maxSize >> 1) : 1);
  		T *tempBuff = new T[maxSize];
  		for (size_t i = 0; l < len; ++i)
   			tempBuff[i] = pBuff[i];
  		if (pBuff != nullptr) delete[] pBuff;
  			pBuff = tempBuff;
  		for (size_t i = len; i < num; ++i)
   			pBuff[i] = elem;
 	}
 	len = num;
}
template<typename T>
void CMyVector<T>::reserve(int num)
{
 	if (num < maxSize)return;
 	else
 	{
 		 maxSize = num;
  		T *tempBuff = new T[maxSize];
  		for (unsigend int i = 0; i < len; ++i)tempBuff[i] = pBuff[i];
  		if (pBuff != nullptr)delete[] pBuff;
  		pBuff = tempBuff;
 	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值