选了数院的数据结构~又要重新写数据结构啥的~~~
我想我一个计算机的~总不能和他们写的一样吧~~于是就写个泛型的容器吧~~
没想到各种困难啊~最先开始的就是语法了~~没想到C++语法还是挺深的~~好多之前都不知道~~
后来不断翻书 才解决~~
还有迭代器~~我是用类实现的~~不知道STL是怎么搞的~~~
下次买本讲STL的书好好学习 下吧~~~收获颇多~~
日志最后有几点小总结~~
list容器方法:
void push_back(T);
iterator erase(iterator);
void clear();
int size();
iterator begin();
iterator end();
代码有点丑:先不管了
《list.h 》
//==========类声明===========
template<class T> class List;
template<class T> class MyIter;
//===========结点类型=============
template<class T>
class ListNode
{
friend class MyIter<T>;
friend class List<T>;
private:
T data;
ListNode *next;
public:
ListNode():next(NULL){};
ListNode(T one)
{
data=one;
next=NULL;
}
};
//===========容器迭代器类============
template<class T>
class MyIter
{
friend class List<T>;
private:
ListNode<T> *p;
public:
//三个构造函数
MyIter():p(NULL){};
MyIter(MyIter& a)
{
p=a.p;
}
MyIter(ListNode<T> *a)
{
p=a;
}
//重载 赋值运算符
MyIter& operator = (const MyIter &a)
{
p=a.p;
return *this;
}
//分别重载 前后++运算符
MyIter& operator ++()
{
if (p==NULL)
{
throw std::out_of_range("小兔齐齐友情提示:迭代器已经到END了");
}
p=p->next;
return *this;
}
MyIter operator ++(int)
{
MyIter ans=p;
if (p==NULL)
{
throw std::out_of_range("小兔齐齐友情提示:迭代器已经到END了");
}
p=p->next;
return ans;
}
//重载 解运算符
T& operator *()
{
return (p->data);
}
//因为 一开始以为比较运算符必须要写在外面,所以写了俩友元函数,后来被大家指出是可以写在里面的
template<class T> friend bool operator == (const MyIter<T>&,const MyIter<T>&);
template<class T> friend bool operator != (const MyIter<T>&,const MyIter<T>&);
};
template<class T>
bool operator == (const MyIter<T> &a,const MyIter<T> &b)
{
return a.p==b.p;
}
template<class T>
bool operator != (const MyIter<T> &a,const MyIter<T> &b)
{
return a.p!=b.p;
}
//============容器类型=============
template<class T>
class List
{
private:
ListNode<T> *head,*tail;
int m_size;
public:
//定义 迭代器
typedef MyIter<T> iterator;
//构造函数,使用冗余头结点 统一操作
List():m_size(0)
{
head = new ListNode<T>();
tail = head;
};
void push_back(T);
iterator erase(iterator);
void clear();
int size()
{
return m_size;
}
//返回头尾迭代器
iterator begin()
{
return iterator(head->next);
}
iterator end()
{
return iterator(NULL);
}
};
//=================================
//==========容器实现===============
template<class T>
void List<T>::push_back(T one)
{
++m_size;
tail->next=new ListNode<T>(one);
tail=tail->next;
}
template<class T>
MyIter<T> List<T>::erase(iterator tar)
{
ListNode<T> *p=head->next,*ppre=head;
iterator r;
while(p!=NULL)
{
if(p==tar.p)
{
ppre->next=p->next;
delete p;
m_size--;
return r=ppre->next;
}
ppre=p;
p=p->next;
}
throw std::invalid_argument("指针无效");
}
template<class T>
void List<T>::clear()
{
ListNode<T> *p1=head,*p2;
while(p1!=NULL)
{
p2=p1->next;
delete p1;
p1=p2;
}
m_size=0;
}
《main.cpp》
/*
E20814061 丁亚光 08软件
模拟List泛型容器
List成员方法:
void push_back(T);
iterator erase(iterator);
void clear();
int size();
iterator begin();
iterator end();
支持迭代器~
*/
#include <iostream>
#include "list.h"
using namespace std;
int main()
{
List<int> L;
L.push_back(1);
L.push_back(2);
L.push_back(3);
L.push_back(1);
L.push_back(2);
L.push_back(3);
//显示元素个数
cout<<L.size()<<endl;
//遍历显示每个元素,并+1
List<int>::iterator it=L.begin();
while(it!=L.end())
{
cout<<*it<<" ";
*it+=1;
it++;
}
cout<<endl;
//删除第一个元素
L.erase(L.begin());
//遍历显示所有元素
it=L.begin();
while(it!=L.end())
{
cout<<*it<<" ";
it++;
}
cout<<endl;
//依次删除所有元素,测试迭代器
it=L.begin();
while(it!=L.end())
{
it=L.erase(it);
}
//L.clear();
//输出元素个数
cout<<endl<<L.size()<<endl;
int a;
cin>>a;
}
问题总结:
1.本来好好的友元,类成员函数的外部实现等等,在泛型下面就变得非常绕了~
2.在类内部 typedef 的类型貌似在外面就没法用了~所以erase的返回类型还是
写的MyIter<T>,即使用List<T>::iterator 也是不行~
(经过大牛指教,应该是typename List<T>::iterator,原因C++ primer上讲了)