您的位置:首页 > 其它

STL模拟实现迭代器

2017-11-04 17:37 369 查看
迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型。

用于提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示,也可以这么说:Iterator模式是运用于聚合对象的一种模式,通过运用该模式,使得我们可以在不知道对象内部表示的情况下,按照一定顺序(由iterator提供的方法)访问聚合对象中的各个元素。

一般仅用于底层聚合支持类,如STL的list、vector、stack等容器类及ostream_iterator等扩展iterator。





一、模拟实现Vector

//完成标准容器Vector
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<assert.h>
#include<string>
//#include"Vector.h"
using namespace std;
//为了提高效率,在此进行类型萃取,将自定义类型与内置类型分开处理
//自定义类型用memcpy会出错,故只能用for循环进行赋值和拷贝
//而如果全部用for循环的话,如果是内置类型,则效率太低,故将其分开
struct TypeFalse
{
static bool IsPODType()
{
return false;
}
};
struct TypeTrue
{
static bool IsPODType()
{
return true;
}
};
template <class T>
struct TypeTail
{
typedef TypeFalse PODType;
};
template<>
struct TypeTail<int>
{
typedef TypeTrue PODType;
};
template<>
struct TypeTail<char>
{
typedef TypeTrue PODType;
};

template<>
struct TypeTail<float>
{
typedef TypeTrue PODType;
};

template<>
struct TypeTail<double>
{
typedef TypeTrue PODType;
};

template <class T>
struct Vector
{
public:
typedef T* Iterator;
typedef const T* ConstIterator;
public:
Vector()
: _start(0)
, _finish(0)
, _endOfStorage(0)
{}

V
4000
ector(const T* array, size_t size)
:_start(new T[size])
, _finish(_start)
, _endOfStorage(_start + size)
{
if (TypeTail<T>::PODType::IsPODType())
{
memcpy(_start, array, sizeof(T)*size);
_finish = _start + size;
}
else
{
for (size_t i = 0; i < size; i++)
{
*_finish++ = array[i];
}
}
}
Vector(const Vector<T>& v)
{
_start = new T[size];
if (TypeTail<T>::PODType::IsPODType())
memcpy(_start, v._start, sizeof(T)*v.Size());
else
{
for (size_t i = 0; i < size; i++)
{
_start[i] = v._start[i];
}
}
_finish = _start + size;
_endOfStorage + size;
}
//Vector& operator=(const Vector<T>& s)
Vector& operator=(const Vector<T>& s)
{
if (this != &s)
{
_start = new T[1];
Vector temp(s);
swap(temp._start, _start);
}
return *this;
}
~Vector()
{
if (_start)
delete[] _start;
_start = _finish = _endOfStorage = 0;
}

//////////////Iterator/////////////////////////////////
Iterator Begin()
{
return _start;
}
Iterator End()
{
return _finish;
}
ConstIterator Begin()const
{
return _start;
}
ConstIterator End()const
{
return _finish;
}
void PushBack(const T& data)
{
_CheckCapacity();
*_finish = data;
++_finish;
}
void PopBack()
{
assert(!Empty());
--_finish;
}
void Insert(size_t pos, const T& data)
{
_CheckCapacity();
size_t size = Size();
assert(pos >= 0 && pos <= size);
for (size_t i = size; i > pos; i--)
{
_start[i] = _start[i - 1];
}
_start[pos] = data;
++_finish;
}
void Erase(size_t pos)
{
size_t size = Size();
assert(pos >= 0 && pos < size);
for (size_t i = pos; i < size - 1; ++i)
{
_start[i] = _start[i + 1];
}
--_finish;
}

//////////////////capacity////////////////////////////
size_t Size()const
{
return _finish - _start;
}
size_t Capacity()const
{
return _endOfStorage - _start;
}
bool Empty()const
{
return _start == _finish;
}
void Resize(size_t newSize, const T& data = T())
{
size_t size = Size();
size_t capacity = Capacity();
if (newSize < size)
{
_finish = _start + newSize;
}
else if (size < newSize&&newSize < capacity)
{
for (size_t i = 0; i < newSize; ++i)
{
*_finish++ = data;
}
_finish = _start + newSize;
}
else//大于容量,需要增容
{

T* temp = new T[newSize];
if (TypeTail<T>::PODType::IsPODType())
memcpy(temp, _start,size*sizeof(T));
else
{
for (size_t i = 0; i < size; i++)
{
temp[i] = _start[i];
}
}
for (size_t i = size; i < newSize; i++)
{
temp[i] = data;
}
delete[] _start;
_start = temp;
_finish = _start + newSize;
_endOfStorage = _start + newSize;
}
}

//////////////Acess///////////////////////////
T& operator[](size_t index)
{
assert(index < Size() && index >= 0);
return _start[index];
}
const T& operator[](size_t index)const
{
assert(index < Size() && index >= 0);
return _start[index];
}
T& Front()
{
return *_start;
}
const T& Front()const
{
return *_start;
}
T& Back()
{
return *(_finish - 1);
}
const T& Back()const
{
return *(_finish - 1);
}
void Clear()
{
_finish = _start;
}

//template<class T>
friend ostream& operator<<(ostream& _cout, const Vector<T>& v)
{
Vector<T>::ConstIterator t1 = v.Begin();
while (t1 != v.End())
{
_cout << *t1 << " ";
++t1;
}
return _cout;
}

private:
void _CheckCapacity()
{
size_t capa = Capacity();
size_t size = Size();
if (size >= capa)
{
size_t capacity = capa ? capa * 2 : 3;
T* temp = new T[capacity];
if (TypeTail<T>::PODType::IsPODType())
memcpy(temp, _start, size*sizeof(T));
else
{
for (size_t i = 0; i < size; i++)
{
temp[i] = _start[i];
}
}
assert(temp);
delete[] _start;
_start = temp;
_finish = _start + size;
_endOfStorage = _start + capacity;
}
}

private:
T* _start;
T* _finish;
T* _endOfStorage;
};


//测试代码:
void TestVector()
{
int arr[] = { 1, 2, 3, 4 };

Vector<int>v1(arr, 4);
cout << v1 << endl;
v1.Insert(0, 0);
v1.Insert(v1.Size(), 5);
v1.Insert(4, -4);
cout << v1 << endl;

v1.Erase(4);
v1.Erase(0);
v1.Erase(v1.Size() - 1);

v1.PopBack();
cout << v1 << endl;
v1.PopBack();
v1.PopBack();
v1.PopBack();
cout << v1 << endl;

v1.PushBack(1);
v1.PushBack(2);
v1.PushBack(3);
v1.PushBack(4);
cout << v1 << endl;

v1.Resize(10, 5);
cout << v1 << endl;

v1.Resize(30);
cout << v1 << endl;

v1.Resize(3);
cout << v1 << endl;
}
void Teststring()
{
string arr[4] = { string("111"), string("2222"),
string("3333"), string("4444") };
Vector<string>v1(arr, 4);
cout << v1 << endl;
v1.Insert(0, string("0000"));
v1.Insert(v1.Size(), string("5555"));
cout << v1 << endl;
v1.Resize(20, string("1234"));
cout << v1 << endl;
}
int main()
{
cout << "TestVector:" << endl << endl;
TestVector();

cout << endl << endl;
cout << "Teststring:" << endl << endl;
Teststring();

getchar();
return 0;
}


运行结果:



二、模拟实现List

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

//完成标准容器List
//对于结点的封装
template<class T>
struct ListNode
{
ListNode(const T& data = T())
: _pPre(0)
, _pNext(0)
, _data(data)
{}

ListNode* _pPre;
ListNode* _pNext;
T _data;
};
//迭代器
//实现指针的功能,比如++,--,解引用 ……
template<class T,class Ref,class Ptr>
class ListIterator
{
typedef ListNode<T> Node;
typedef ListIterator Self;
public:
Self()
: _pCur(0)
{}

Self(Node* pCur)
: _pCur(pCur)
{}

Self(const Self& s)
: _pCur(s._pCur)
{}

T operator*()
{
return _pCur->_data;
}

Ptr operator->()
{
return &(operator*());
//return &(_pCur->_data);
}

Self& operator++()
{
_pCur = _pCur->_pNext;
return*this;
}

Self operator++(int)
{
Self temp(*this);
_pCur = _pCur->_pNext;
return temp;
}

Self& operator--()
{
_pCur = _pCur->_pPre;
return*this;
}

Self operator--(int)
{
Self temp(*this);
_pCur = _pCur->_pPre;
return temp;
}

bool operator!=(const Self& s)
{
return _pCur != s._pCur;
}

bool operator==(const Self& s)
{
return _pCur == s._pCur;
}

Node* _pCur;
};

//List:
template<class T>
class List
{
public:
typedef ListNode<T> Node;
typedef ListIterator<T, T*, T&> Iterator;
//typedef ListIterator<T, const T*, const T&> ConstIterator;
public:
List()
: _pHead(new Node)
{
_pHead->_pNext = _pHead;
_pHead->_pPre = _pHead;
}

// 1 2 3 4 5
List(const T* array, size_t size)
{
if (_pHead == NULL)
{
_pHead = new Node;
_pHead->_pNext = _pHead;
_pHead->_pPre = _pHead;
}
for (size_t i = 0; i < size; i++)
{
PushBack(array[i]);
}
}
List(/*const*/ List& l)
{
size_t size = l.Size();
Node* temp =l._pHead->_pNext;
_pHead = new Node;
_pHead->_pNext = _pHead;
_pHead->_pPre = _pHead;
while (size--)
{
PushBack(temp->_data);
temp = temp->_pNext;
}
}
List& operator=(const List& l)
{
if (&l == this)
return *this;
List temp(l);
swap(l._pHead, _pHead);
}
~List()
{
Clear();
if (_pHead)
delete _pHead;
_pHead = 0;
}

/////////////////////////////////////////////////////
Iterator Begin()
//ConstIterator Begin()const
{
//return Iterator(_pHead->_pNext);
return _pHead->_pNext;
}

//ConstIterator End()const
Iterator End()
{
//return Iterator(_pHead);
return _pHead;
}
/////////////////////Modify//////////////////////////
void PushBack(const T& data)
{
Insert(End(), data);
}
void PopBack()
{
Erase(Iterator(_pHead->_pPre));

}
void PushFront(const T& data)
{
Insert(Begin(), data);
}
void PopFront()
{
Erase(Begin());
}
Iterator Insert(Iterator pos, const T& data)
{
Node* Pos = pos._pCur;
Node* NewNode = new Node(data);

NewNode->_pNext = Pos;
NewNode->_pPre = Pos->_pPre;
Pos->_pPre->_pNext = NewNode;
Pos->_pPre = NewNode;
//return Iterator(NewNode);
return NewNode;
}
Iterator Erase(Iterator pos)
{
Iterator it = Begin();
while (it != End())
{
if (*it == *pos)
{
Node* temp = pos._pCur;
temp->_pPre->_pNext  = temp->_pNext;
temp->_pNext->_pPre = temp->_pPre;
pos = temp->_pPre;
return Iterator(pos);
}
++it;
}
return End();
}
bool Empty()const
{
return _pHead->_pNext == _pHead;
}
template<class T>
Iterator Find(const T&data)
{
List<T>::Iterator it = Begin();
while (it != End())
{
if (*it == data)
return it;
++it;
}
}
size_t Size()/*const*/
{
size_t count = 0;
/*Const*/Iterator it = Begin();
while (it != End())
{
++count;
++it;
}
return count;
}
T& Front()
{
return _pHead->_pNext->_data;
}
const T& Front()const
{
return _pHead->_pNext->_data;
}
T& Back()
{
return _pHead->_pPre->_data;
}
const T& Back()const
{
return _pHead->_pPre->_data;
}
void Clear()
{
Node* temp = _pHead->_pNext;
while (temp != _pHead)
{
PopBack();
}
}
friend ostream&operator<<(ostream&_cout, /*const*/ List<T>&l)
{
List<T>::/*Const*/Iterator it = l.Begin();
while (it != l.End())
{
_cout << *it << "->";
++it;
}
cout << "->NULL" << endl;
return _cout;
}
private:
ListNode<T>* _pHead;
};


//测试代码:
void TestList1()
{
int array[] = { 1, 2, 3, 4, 5, 6, 7 };
List<int> l(array, sizeof(array) / sizeof(array[0]));
cout << l << endl;

l.PushBack(8);
l.PushFront(0);
cout << l << endl;
cout << l.Size() << endl;

List<int>::Iterator pos = l.Find(2);
l.Insert(pos, 7);
cout << l << endl;

l.Erase(pos);
cout << l << endl;

l.Clear();
cout << l.Size() << endl;
}
void TestList2()
{
int array[] = { 1, 2, 3, 4, 5, 6, 7 };
List<int> s1(array, sizeof(array) / sizeof(array[0]));
cout <<"s1="<< s1 << endl;

List<int> s2(s1);
cout <<"s2(s1): s2="<< s2 << endl;

List<int> s3 = s1;
cout << "s3=s1: s3=" << s3 << endl;
}

int main()
{
TestList1();
TestList2();
getchar();
return 0;
}


运行结果:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: