使用C++实现Vector

最近开始学习数据结构与算法了,使用的是Weiss的数据结构与算法C++描述,第三版和第四版。

其中第四版已经全部用C++11的标准重写了。

感觉我自己写的时候有点纠结到底用C++老的标准还是C++11的标准,哈哈,选择困难!


今天我主要用C++老的标准写了Vector类,因此没有实现移动构造函数和移动拷贝函数。但是里面使用了C++11中的auto和nullptr这两个东西,auto确实很方便。


记录一下今天的代码:

首先是Vector.h文件,里面定义了Vector类模板


#ifndef MY_VECTOR_H
#define MY_VECTOR_H
#include<new> //因为程序中使用了nothrow new
#include<iostream>
template <typename Object>
class Vector{

public:
	enum {SPARE_CAPACITY=16}; //为Vector类保留初始化的容量————常量
	typedef Object * iterator; //普通迭代器
	typedef const Object * const_iterator; //常迭代器

// 提供的函数
public:

	// 构造函数 + 默认构造函数(使用explicit防止隐式转换)
	explicit Vector(int initSize = 0) 
		:m_theSize(initSize), 
		m_theCapacity(m_theSize + SPARE_CAPACITY),
		m_po(nullptr) //指针直接初始化为nullptr
	{ 
		m_po = new(std::nothrow) Object[m_theCapacity];
		if (nullptr == m_po) //分配失败就直接停机
		{
			std::cerr << "FAILED! IN CONSTRUCTOR!" << endl;
			exit(0);
		}
	}

	// 拷贝构造函数
	Vector(const Vector & rhs) 
		:m_theSize(rhs.m_theSize),
		m_theCapacity(rhs.m_theCapacity),
		m_po(nullptr) 
	{
		m_po = new(std::nothrow) Object[m_theCapacity];
		if (nullptr == m_po)
		{
			std::cerr << "FAILED! IN COPY CONSTRUCTOR!" << endl;
			exit(0);
		}
		for (unsigned int i = 0; i < rhs.m_theSize; ++i)
		{
			this->m_po[i] = rhs.m_po[i];
		}

	}

	//重载赋值操作符
	const Vector& operator=(const Vector & rhs)
	{
		if (this != &rhs) // 防止自复制
		{
			// 先申请资源,而不是先释放被赋值的对象
			// 防止如果释放后,重新申请内存失败
			Object *p_tmp = new(std::nothrow) Object[rhs.m_theCapacity];
			if (nullptr == p_tmp)
			{
				std::cerr << "FAILED! IN COPY ASSIGNMENT!" << endl;
				exit(0);
			}
			// 赋值到新的内存
			for (unsigned int i = 0; i < rhs.m_theSize; ++i)
			{
				p_tmp[i] = rhs.m_po[i];
			}
			// 释放原对象内存
			delete[] this->m_po;
			this->m_po = p_tmp; // 接管内存
			this->m_theSize = rhs.m_theSize;
			this->m_theCapacity = rhs.m_theCapacity;
		}
		return *this;
	}

	// 析构函数
	~Vector()
	{
		delete[] this->m_po;
	}

	// resize函数用来改变Vector的Size
	void resize(unsigned int newSize)
	{
		if (this->m_theCapacity < newSize)
			reverve(newSize * 2 + 1);
		this->m_theSize = newSize;
	}

	// reserve函数用来改变Vector的Capacity
	void reverse(unsigned int newCapacity)
	{
		if (this->m_theSize > newCapacity)
			return;

		Object *p_tmpNew = new(std::nothrow) Object[newCapacity];
		if (nullptr == p_tmpNew)
		{
			std::cerr << "FAILED! IN COPY ASSIGNMENT!" << endl;
			exit(0);
		}

		for (unsigned int i = 0; i < m_theSize; ++i)
		{
			p_tmpNew[i] = this->m_po[i];
		}

		delete[] m_po;
		this->m_po = p_tmpNew;
		this->m_theCapacity = newCapacity;
	}

	// 重载[]操作符(包含两种)
	// 1、对于常对象使用的[]
	const Object& operator[] (unsigned int index) const
	{
		if (index > this->m_theSize)
		{
			cerr << "ERROR! overstepped the boundary!" << endl;
			exit(0);
		}
		return this->m_po[index];
	}
	// 2、非常对象使用的[], 使用1中的代码,减少冗余
	Object & operator[] (unsigned int index)
	{
		return const_cast<Object&>(
			static_cast<const Vector &>(*this)[index]);
	}

	// 判断vector对象内部是否为空
	bool empty() const
	{
		return (0 == m_theSize) ? true : false;
	}

	// 获得vector对象的含有元素的个数
	unsigned int size() const
	{
		return m_theSize;
	}

	// 获得vector对象的总容量
	unsigned int capacity() const
	{
		return m_theCapacity;
	}
	
	// 在vector对象的尾部插入元素
	void push_back(const Object &tmp)
	{
		if (m_theSize == m_theCapacity)
		{
			reverse(2 * m_theCapacity + 1);
		}
		m_po[m_theSize++] = tmp;
	}

	// 删除vector最后的一个元素
	void pop_back()
	{
		if (0 == m_theSize)
		{
			cerr << "ERROR! THERE IS NO VALUE IN THE VECTOR!" << endl;
			exit(0);
		}
		else
		{
			--m_theSize;
		}		
	}

	// 返回最后一个元素的值
	const Object & back() const
	{
		if (0 == m_theSize)
		{
			cerr << "ERROR! THERE IS NO VALUE IN THE VECTOR!" << endl;
			exit(0);
		}
		else
		{
			return m_po[m_theSize - 1];
		}
	}

	// 实现begin函数,返回指向第一个元素的迭代器
	iterator begin()
	{
		return &m_po[0];
	}
	const_iterator begin() const
	{
		reutrn &m_po[0];
	}

	// 实现end函数,返回指向最后一个元素之后的位置的迭代器
	iterator end()
	{
		return &m_po[m_theSize]; //注意是m_theSize,而不是m_theSize-1
	}
	const_iterator end() const
	{
		return &m_po[m_theSize];
	}


private: //注意声明的顺序,因为构造函数中赋值按此顺序
	unsigned int m_theSize;
	unsigned int m_theCapacity;
	Object *m_po;
};

#endif

下面是测试代码:demoTest.cpp

#include<iostream>
#include<algorithm> // 使用了copy函数
#include<iterator>  // 使用了ostream_iterator
#include<windows.h> // 使用了Sleep函数
#include"Vector.h"
using namespace std;

int main()
{
	cout << "----------下面测试Vector----------"<<endl;
	Sleep(1000);

	cout << "-----测试增加元素,begin和end函数--------" << endl;
	Vector<int> myVec;
	myVec.push_back(1);
	myVec.push_back(2);
	myVec.push_back(3);
	copy(myVec.begin(), myVec.end(), ostream_iterator<int>(cout, " "));
	cout << endl;
	Sleep(1000);

	cout << "-----测试拷贝构造函数--------" << endl;
	Vector<int> tmpV1(myVec);
	copy(tmpV1.begin(), tmpV1.end(), ostream_iterator<int>(cout, " "));
	cout << endl;
	Sleep(1000);

	cout << "-----测试拷贝赋值函数--------" << endl;
	Vector<int> tmpV2;
	tmpV2 = tmpV1;
	copy(tmpV2.begin(), tmpV2.end(), ostream_iterator<int>(cout, " "));
	cout << endl;
	Sleep(1000);

	cout << "-----测试empty,size,capacity,pop_back函数--------" << endl;
	cout << "capacity = " << myVec.capacity() << endl;
	cout << "size = " << myVec.size() << endl;
	while (!myVec.empty())
	{
		myVec.pop_back();
	}
	cout << "----------vector已经清空--------------------" << endl;
	Sleep(1000);


	cout << "----------测试resize和reverse函数-----------" << endl;
	auto tmp_size = myVec.size();
	auto tmp_capacity = myVec.capacity();
	for (int i = 0; i < 50; i++)
	{
		if (0 == i)
		{
			cout << "* i=" << i << " , size=" << myVec.size() << " ,capacity=" << myVec.capacity() << endl;
		}
		myVec.push_back(i);
		if (tmp_capacity != myVec.capacity())//(tmp_size != myVec.size()) || (
		{
			tmp_size = myVec.size();
			tmp_capacity = myVec.capacity();
			cout << "* i=" << i << " , size=" << myVec.size() << " ,capacity=" << myVec.capacity() << endl;
		}	
		
	}
	cout << "------现在vector中的内容------" << endl;
	copy(myVec.begin(), myVec.end(), ostream_iterator<int>(cout, " "));
	cout << endl;

	return 0;
}


运行结果:



运行平台:windows10+VS2013

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值