写在前面
????????该题目源于哈工大竞技机器人队视觉组暑期培训,感觉很有意思,决定放在博客上留存。
题目
????????动手实现Vector,要求如下:
-
自己动手实现一个泛型的动态数组,并实现Vector中的部分操作:push_back、pop_back、.at、[]、clear和复制构造函数。要求构造和析构正确。(注意是动态数组,所以要求不能直接使用普通的定长数组或者链表实现)要求main中有该类对象的调用。 -
对上述的程序添加预编译命令,使得其在DEBUG阶段加入一些调试信息,可以是当前数组长度的输出,可以是当前在哪个函数内的输出。并使得在RELEASE时不输出这些信息。 -
上述的程序需要使用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;
}
|