【C++】自己编写函数实现Vector部分功能

写在前面

        该题目源于哈工大竞技机器人队视觉组暑期培训,感觉很有意思,决定放在博客上留存。

题目

        动手实现Vector,要求如下:

  1. 自己动手实现一个泛型的动态数组,并实现Vector中的部分操作:push_back、pop_back、.at、[]、clear和复制构造函数。要求构造和析构正确。(注意是动态数组,所以要求不能直接使用普通的定长数组或者链表实现)要求main中有该类对象的调用。

  2. 对上述的程序添加预编译命令,使得其在DEBUG阶段加入一些调试信息,可以是当前数组长度的输出,可以是当前在哪个函数内的输出。并使得在RELEASE时不输出这些信息。

  3. 上述的程序需要使用CMake编译工具,写好程序该有的框架。

C++代码

vector.h

#ifndef _VECTOR_H_
#define _VECTOR_H_

#include <iostream>
#include <assert.h>
using namespace std;

template <class T>
class Vector
{
public:
	//Vector迭代器的原生指针
	typedef T* iterator;
	//const迭代器
	typedef const T* const_iterator;

	iterator begin()
	{
		return _start;
	}
	iterator end()
	{
		return _finish;
	}
	const_iterator cbegin() const
	{
		return _start;
	}
	const_iterator cend() const
	{
		return _finish;
	}
	
	//构造函数
	Vector()
	{
		_start=nullptr;
		_finish=nullptr;
		_end_of_storage=nullptr;
	}

	//复制构造函数
	Vector(const Vector<int>& v):_start(nullptr),_finish(nullptr), _end_of_storage(nullptr)
	{
		Reserve(v.Capacity());
		iterator it = begin();
		const_iterator vit = v.cbegin();
		while (vit != v.cend())
		{
			*it++ = *vit++;
		}
		_finish = _start + v.Size();
		_end_of_storage = _start + v.Capacity();
	}

	//析构函数
	~Vector()
	{
		if (_start)
		{
			delete[] _start;	//释放_start指向的内存
			_start = _finish = _end_of_storage = nullptr;
		}
	}

	//在Vector中任意位置前插入一个数
	void Insert(iterator pos, const T& x)
	{
		assert(pos <= _finish);
		size_t posindex = pos - _start;
		if (_finish == _end_of_storage)
		{
			size_t newcapacity = Capacity() == 0 ? 2 : Capacity() * 2;
			Reserve(newcapacity);
			pos = _start + posindex;
		}
		iterator end = _finish;
		while (end > pos)
		{
			*end = *(end - 1);
			--end;
		}
		*pos = x;
		++_finish;
	}

	//删除Vector任意位置中的数
	iterator Erase(iterator pos)
	{
		iterator begin = pos;
		while (pos != _finish)
		{
			*pos = *(pos + 1);
				++pos;
		}
		--_finish;
		return begin;
	}

	//PushBack实现(往Vector中插入数据)
	void PushBack(const T& x)
	{
		Insert(end(), x);
	}

	//PopBack实现(在Vector后插入数据)
	void PopBack()
	{
		assert(Size() > 0);
		--_finish;
	}

	//实现clear
	void clear()
	{
		while(begin()!=end())
		{
			Erase(end());
		}
	}

	//实现at
	T at(T pos)
	{
		return _start[pos];
	}

	//实现[]访问Vector
	T& operator [](size_t pos)
	{
		assert(pos < Size());
		return _start[pos];
	}

	//增容Capacity
	void Reserve(size_t n) 
	{
		if (n > Capacity())
		{
			size_t size = Size();
			T* tmp = new T[n];
			if (_start)
			{
				//memcpy(tmp, _start, sizeof(T)*size);
				for (size_t i = 0; i < size; ++i)
				{
					tmp[i] = _start[i];
				}
			}
			_start = tmp;
			_finish = _start + size;
			_end_of_storage = _start + n;
		}
	}
	
	size_t Size() const
	{
		return _finish - _start;
	}
	
	size_t Capacity() const
	{
		return _end_of_storage - _start;
	}
	
private:
	//给每个成员都赋上缺省值
	iterator _start = nullptr;
	iterator _finish = nullptr;
	iterator _end_of_storage = nullptr;

};

#endif

vector.cpp

#include"vector.h"

void PushBack_Test()
{
	cout << "You are testing PushBack() now:" << endl;
	Vector<int> v1;
	v1.PushBack(1);
	v1.PushBack(2);
	v1.PushBack(3);
	v1.PushBack(4);
	v1.PushBack(5);
	for (size_t i = 0; i < v1.Size(); ++i)
	{
		cout << v1[i] << " ";
	}
	cout << endl;
	#ifdef DEBUG
		cout << "Size of vector: " << v1.Size()<< endl;
	#endif
	cout << endl;
}

void PopBack_Test()
{
	cout << "You are testing PopBack() now:" << endl;
	Vector<int> v1;
	v1.PushBack(1);
	v1.PushBack(2);
	v1.PushBack(3);
	v1.PushBack(4);
	v1.PushBack(5);
	for (size_t i = 0; i < v1.Size(); ++i)
	{
		cout << v1[i] << " ";
	}
	cout << endl;
	#ifdef DEBUG
		cout << "Size of origin vector v1: " << v1.Size()<< endl;
	#endif
	v1.PopBack();
	for (size_t i = 0; i < v1.Size(); ++i)
	{
		cout << v1[i] << " ";
	}
	cout << endl;
	#ifdef DEBUG
		cout << "Size of vector after v1.PopBack(): " << v1.Size()<< endl;
	#endif
	cout << endl;
}

void clear_Test()
{
	cout << "You are testing clear() now:" << endl;
	Vector<int> v1;
	v1.PushBack(1);
	v1.PushBack(2);
	v1.PushBack(3);
	v1.PushBack(4);
	v1.PushBack(5);
	for (size_t i = 0; i < v1.Size(); ++i)
	{
		cout << v1[i] << " ";
	}
	cout << endl;
	#ifdef DEBUG
		cout << "Size of origin vector v1: " << v1.Size()<< endl;
	#endif
	v1.clear();
	#ifdef DEBUG
		cout << "Size of vector after v1.clear(): " << v1.Size()<< endl;
	#endif
	cout << endl;
}

void at_Test()
{
	cout << "You are testing at() now:" << endl;
	Vector<int> v1;
	v1.PushBack(1);
	v1.PushBack(2);
	v1.PushBack(3);
	v1.PushBack(4);
	v1.PushBack(5);
	for (size_t i = 0; i < v1.Size(); ++i)
	{
		cout << v1[i] << " ";
	}
	cout << endl;
	#ifdef DEBUG
		cout << "Size of origin vector v1: " << v1.Size()<< endl;
	#endif
	cout << "return v1.at(0): " << v1.at(0) << endl;
	cout << endl;
}

void operator_Test()
{
	cout << "You are testing [] now:" << endl;
	Vector<int> v1;
	v1.PushBack(1);
	v1.PushBack(2);
	v1.PushBack(3);
	v1.PushBack(4);
	v1.PushBack(5);
	for (size_t i = 0; i < v1.Size(); ++i)
	{
		cout << v1[i] << " ";
	}
	cout << endl;
	#ifdef DEBUG
		cout << "Size of origin vector v1: " << v1.Size()<< endl;
	#endif
	cout << "return v1[0]: " << v1[0] << endl;
	cout << endl;
}


void copy_constructor_Test()
{
	cout << "You are testing copy constructor now:" << endl;
	Vector<int> v1;
	v1.PushBack(1);
	v1.PushBack(2);
	v1.PushBack(3);
	v1.PushBack(4);
	v1.PushBack(5);
	for (size_t i = 0; i < v1.Size(); ++i)
	{
		cout << v1[i] << " ";
	}
	cout << endl;
	#ifdef DEBUG
		cout << "Size of origin vector v1: " << v1.Size()<< endl;
	#endif
	Vector<int> v2(v1);
	for (size_t i = 0; i < v2.Size(); ++i)
	{
		cout << v2[i] << " ";
	}
	cout << endl;
	#ifdef DEBUG
		cout << "Size of copied vector v2(v1): " << v2.Size()<< endl;
	#endif
}

main.cpp

#include"vector.cpp"
#define DEBUG

int main()
{
	#ifdef DEBUG
		cout << "You Are In Debug Mode." << endl;
	#endif
	PushBack_Test();
	PopBack_Test();
	clear_Test();
	at_Test();
	operator_Test();
	copy_constructor_Test();
	return 0;
}
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Quentin_HIT

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

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

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

打赏作者

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

抵扣说明:

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

余额充值