C++自制vector容器(带迭代器)

C++的STL库中提供了很多数据结构,用起来很方便,但了解底层原理也是很重要的,它可以帮助我们提高编程水平。本人最近就模仿STL制作了一个vector容器。代码如下:

#pragma once
#include<stdexcept>
template<typename type>
class CVector
{
    
    
public:
	//迭代器类
	class CIterator
	{
    
    
	public:
		//构造函数
		CIterator()noexcept;
		CIterator(type* p)noexcept;
		CIterator(const CIterator& i)noexcept;
		//运算符重载
		type& operator*()const;
		CIterator& operator++();
		CIterator& operator--();
		CIterator operator++(int);
		CIterator operator--(int);
		CIterator operator+(int offset)const;
		CIterator operator-(int offset)const;
		CIterator& operator+=(int offset);
		CIterator& operator-=(int offset);
		size_t operator-(const CIterator& iter);
		type& operator[](int offset);
		friend auto operator<=>(const CIterator& a, const CIterator& b) = default;
	private:
		type* m_p;
	};

	//构造函数

	CVector()noexcept;
	CVector(size_t nSize);
	CVector(size_t nSize, const type& t);
	CVector(const CVector& t);
	CVector(CIterator Begin, CIterator End);

	//随机访问函数

	type& operator[](size_t index)const;
	type& At(size_t index)const;
	type& Front()const;
	type& Back()const;
	size_t FindFirst(const type& t)const;
	size_t FindLast(const type& t)const;
	CIterator Begin()const noexcept;
	CIterator End()const noexcept;

	//修改函数

	void PushBack(const type& t);
	void PopBack()noexcept;
	void Erase(size_t nPos);
	void Erase(size_t nPos, size_t count);
	void Insert(size_t nPos, const type& t);
	void Insert(size_t nPos, size_t count, const type& t);
	void Clear()noexcept;
	void Swap(CVector& v)noexcept;
	CVector<type>& operator=(const CVector& t);

	//容器信息函数

	size_t Size()const noexcept;//实际元素个数
	size_t Capacity()const noexcept;//当前内存所能容纳的最多元素个数
	bool Empty()const noexcept;//判断是否为空
	bool operator==(const CVector& v)const noexcept;
	bool operator!=(const CVector& v)const noexcept;
	//析构函数

	~CVector();
private:
	void SetMem(size_t t = 64);
	type* m_data;
	size_t m_size;//实际元素个数
	size_t m_len;//内存长度
};

template<typename type>
CVector<type>::CVector()noexcept
	:m_data(nullptr), m_len(0), m_size(0)
{
    
    
}

template<typename type>
CVector<type>::CVector(size_t nSize)
	: m_data(new type[nSize]()), m_len(nSize), m_size(nSize)
{
    
    
}

template<typename type>
CVector<type>::CVector(size_t nSize, const type& t)
	: m_data(new type[nSize]), m_len(nSize), m_size(nSize)
{
    
    
	for (size_t i = 0; i < nSize; i++)
		m_data[i] = t;
}

template<typename type>
CVector<type>::CVector(const CVector& t)
	: m_data(new type[t.m_len]), m_len(t.m_len), m_size(t.m_size)
{
    
    
	for (size_t i = 0; i < t.m_size; i++)
		m_data[i] = t.m_data[i];
}

template<typename type>
CVector<type>::CVector(CIterator Begin, CIterator End) :m_size(End - Begin), m_len(m_size), m_data(new type[End - Begin])
{
    
    
	for (size_t i = 0; i < m_size; i++)
		m_data[i] = *Begin++;
}

template<typename type>
size_t CVector<type>::Size() const noexcept
{
    
    
	return m_size;
}

template<typename type>
size_t CVector<type>::Capacity() const noexcept
{
    
    
	return m_len;
}

template<typename type>
bool CVector<type>::Empty() const noexcept
{
    
    
	return !m_size;
}

template<typename type>
bool CVector<type>::operator==(const CVector& v)const noexcept
{
    
    
	if (this->m_size != v.m_size)
		return false;
	for (size_t i = 0; i < m_size; i++)
	{
    
    
		if (this->At(i) != v.At(i))
			return false;
	}
	return true;
}

template<typename type>
bool CVector<type>::operator!=(const CVector& v) const noexcept
{
    
    
	return !(this->operator==(v));
}

template<typename type>
void CVector<type>::Swap(CVector& v)noexcept
{
    
    
	type* temp = m_data;
	m_data = v.m_data;
	v.m_data = temp;
	size_t t = m_size;
	m_size = v.m_size;
	v.m_size = t;
	t = m_len;
	m_len = v.m_len;
	v.m_len = t;
}

template<typename type>
CVector<type>& CVector<type>::operator=(const CVector& t)
{
    
    
	if (m_len < t.m_size)
	{
    
    
		SetMem(t.m_size + 64);
	}
	m_size = t.m_size;
	for (size_t i = 0; i < t.m_size; i++)
		m_data[i] = t.m_data[i];
	return *this;
}

template<typename type>
type& CVector<type>::operator[](size_t index)const
{
    
    
	if (index >= m_size)
		throw std::out_of_range("下标越界!");
	return m_data[index];
}

template<typename type>
type& CVector<type>::At(size_t index) const
{
    
    
	if (index >= m_size)
		throw std::out_of_range("下标越界!");
	return m_data[index];
}

template<typename type>
type& CVector<type>::Front() const
{
    
    
	if (m_size == 0)
		throw std::out_of_range("容器为空!");
	return m_data[0];
}

template<typename type>
type& CVector<type>::Back() const
{
    
    
	if (m_size == 0)
		throw std::out_of_range("容器为空!");
	return m_data[m_size - 1];
}

template<typename type>
size_t CVector<type>::FindFirst(const type& t)const
{
    
    
	for (size_t i = 0; i < m_size; i++)
	{
    
    
		if (m_data[i] == t)
			return i;
	}
	return -1;
}

template<typename type>
size_t CVector<type>::FindLast(const type& t)const
{
    
    
	for (int i = m_size - 1; i >= 0; i--)
	{
    
    
		if (m_data[i] == t)
			return i;
	}
	return -1;
}

template<typename type>
CVector<type>::CIterator CVector<type>::Begin() const noexcept
{
    
    
	return CIterator(m_data);
}

template<typename type>
CVector<type>::CIterator CVector<type>::End() const noexcept
{
    
    
	return CIterator(m_data + m_size);
}

template<typename type>
void CVector<type>::PushBack(const type& t)
{
    
    
	if (m_size == m_len)//容器已满
	{
    
    
		SetMem(m_size + 64);
	}
	m_data[m_size++] = t;
}

template<typename type>
void CVector<type>::PopBack()noexcept
{
    
    
	if (m_size != 0)
		m_size--;
}

template<typename type>
void CVector<type>::Erase(size_t nPos)
{
    
    
	if (nPos >= m_size)
		throw std::out_of_range("下标越界!");
	for (size_t i = nPos + 1; i < m_size; i++)
		m_data[i - 1] = m_data[i];
	m_size--;
}

template<typename type>
void CVector<type>::Erase(size_t nPos, size_t count)
{
    
    
	if (nPos + count - 1 >= m_size)
		throw std::out_of_range("下标越界!");
	for (size_t i = nPos + count; i < m_size; i++)
		m_data[i - count] = m_data[i];
	m_size -= count;
}

template<typename type>
void CVector<type>::Insert(size_t nPos, const type& t)
{
    
    
	if (nPos >= m_size)
		throw std::out_of_range("下标越界!");
	if (m_size == m_len)//容器已满
	{
    
    
		SetMem(m_size + 64);
	}
	for (size_t i = nPos; i < m_size; i++)
		m_data[i + 1] = m_data[i];
	m_data[nPos] = t;
	m_size++;
}

template<typename type>
void CVector<type>::Insert(size_t nPos, size_t count, const type& t)
{
    
    
	if (nPos >= m_size)
		throw std::out_of_range("下标越界!");
	if (m_size + count > m_len)
	{
    
    
		SetMem(m_size + count + 64);
	}
	for (size_t i = nPos; i < m_size; i++)
		m_data[i + count] = m_data[i];
	for (size_t i = nPos; i < nPos + count; i++)
		m_data[i] = t;
	m_size += count;
}

template<typename type>
void CVector<type>::Clear()noexcept
{
    
    
	m_size = 0;
}

template<typename type>
CVector<type>::~CVector()
{
    
    
	if (m_data != nullptr)
		delete[]m_data;
}

template<typename type>
void CVector<type>::SetMem(size_t t)
{
    
    
	type* temp = new type[m_len];
	for (size_t i = 0; i < m_size; i++)
		temp[i] = m_data[i];
	if (m_data != nullptr)
		delete[] m_data;
	m_data = new type[m_len = t];
	for (size_t i = 0; i < m_size; i++)
		m_data[i] = temp[i];
	delete[] temp;
}

template<typename type>
CVector<type>::CIterator::CIterator()noexcept :m_p(nullptr)
{
    
    
}

template<typename type>
CVector<type>::CIterator::CIterator(type* p)noexcept : m_p(p)
{
    
    
}

template<typename type>
CVector<type>::CIterator::CIterator(const CVector<type>::CIterator& i)noexcept : m_p(i.m_p)
{
    
    
}

template<typename type>
type& CVector<type>::CIterator::operator*()const
{
    
    
	return *m_p;
}

template<typename type>
CVector<type>::CIterator& CVector<type>::CIterator::operator++()
{
    
    
	m_p++;
	return *this;
}

template<typename type>
CVector<type>::CIterator& CVector<type>::CIterator::operator--()
{
    
    
	m_p--;
	return *this;
}

template<typename type>
CVector<type>::CIterator CVector<type>::CIterator::operator++(int)
{
    
    
	CIterator temp(*this);
	m_p++;
	return temp;
}

template<typename type>
CVector<type>::CIterator CVector<type>::CIterator::operator--(int)
{
    
    
	CIterator temp(*this);
	m_p--;
	return temp;
}

template<typename type>
CVector<type>::CIterator CVector<type>::CIterator::operator+(int offset)const
{
    
    
	return CIterator(this->m_p + offset);
}

template<typename type>
CVector<type>::CIterator CVector<type>::CIterator::operator-(int offset)const
{
    
    
	return CIterator(this->m_p - offset);
}

template<typename type>
CVector<type>::CIterator& CVector<type>::CIterator::operator+=(int offset)
{
    
    
	m_p += offset;
	return *this;
}

template<typename type>
CVector<type>::CIterator& CVector<type>::CIterator::operator-=(int offset)
{
    
    
	m_p -= offset;
	return *this;
}

template<typename type>
size_t CVector<type>::CIterator::operator-(const CIterator& iter)
{
    
    
	return this->m_p - iter.m_p;
}

template<typename type>
type& CVector<type>::CIterator::operator[](int offset)
{
    
    
	return *(operator+(offset));
}

猜你喜欢

转载自blog.csdn.net/qq_54121864/article/details/118673092