(四)STL剖析——List

List.h

#ifndef __List__
#define __List__

#include "Iterator.h"
#include "Alloc.h"
#include "Construct.h"

//STL对于区间前闭后开

//List的节点
template<class T>
struct ListNode
{
	typedef ListNode<T>* Node_p;
	Node_p _prev;
	Node_p _next;
	T _data;
	ListNode(const T& data=T() )
		:_prev(NULL)
		, _next(NULL)
		, _data(data)
	{}
};

//List中的迭代器(由于list不是线性空间结构,通用迭代器无法正常移动,所以list需要定义专门的迭代器。)
template<class T,class Ref,class Ptr>//???????????????
struct __ListIterator
{
	//List使用的迭代器应该是可双向移动的(五种相应型别必须有,或者继承struct Iterator)
	typedef BidirectionalIteratorTag IteratorCategory;
	typedef T ValueType;
	typedef Ptr Pointer;
	typedef Ref Reference;
	typedef ptrdiff_t DifferenceType;

	typedef __ListIterator<T, Ref, Ptr> Self;

	typedef ListNode<T> Node, *Node_p;
	Node_p _node;

	//__ListIterator(Node_p x) 
	//	: _node(x) 
	//{}
	__ListIterator()
	{}
	__ListIterator(Node_p node)
		:_node(node)
	{}
	//取节点的数值
	Ref operator*()const
	{
		return _node->_data;
	}
	Ptr operator->()const
	{
		return &(operator*());
	}
	bool operator == (const Self& x)
	{
		return (_node==x._node);
	}
	bool operator != (const Self& x)
	{
		return (_node != x._node);
	}
	Self& operator++()
	{
		_node = _node->_next;
		return *this;
	}
	Self operator++(int)
	{
		Self old = *this;
		++(*this);
		return old;
	}
	Self& operator--()
	{
		(_node = _node->_prev);
		return *this;
	}
	Self operator--(int)
	{
		Self old = *this;
		--(*this);
		return old;
	}
};

//template <class T, class Ref, class Ptr>
// BidirectionalIteratorTag IteratorCategory(const __ListIterator<T, Ref, Ptr>&) 
//{
//		return BidirectionalIteratorTag();
//}
//template <class T, class Ref, class Ptr>
//T* ValueType(const __ListIterator<T, Ref, Ptr>&) 
//{
//	return 0;
//}
//template <class T, class Ref, class Ptr>
//ptrdiff_t* DistanceType(const __ListIterator<T, Ref, Ptr>&) 
//{
//	return 0;
//}

//List是一个带头结点的双向循环链表
template<class T, class Alloc = alloc>
class List
{
public:
	typedef SimpleAlloc<ListNode<T>, Alloc> ListNodeAllocator;

	typedef __ListIterator<T, T&, T*> Iterator;//STL强制要求
	typedef __ListIterator<T, const T&, const T*> ConstIterator;

	typedef T ValueType;
	typedef T& Reference;
	typedef const T& ConstReference;
	typedef T* Pointer;
	typedef const T* ConstPointer;
	//typedef List<T, Alloc> Self;
private:
	typedef ListNode<T> Node, *Node_p;

	Node* CreateNode(size_t size,const T& data=T())
	{
		//Node_p node = new Node(data);
		//分配内存
		Node* node = ListNodeAllocator::Allocate(size);
		//配置空间
		Construct(node, data);
		return node;
	}
	void DestroyNode(Node_p node)
	{
		//调用析构
		Destroy(node);
		//释放内存
		ListNodeAllocator::Deallocate(node);
	}

public:
	List()
		:_list(CreateNode(sizeof(Node)))
	{
		_list->_next = _list;
		_list->_prev = _list;
	}
	//List(Iterator first,Iterator last);
	//List(const List<T, Alloc>& l);
	//List<T,Alloc>& operator=(const List<T,Alloc>& l);
	~List()
	{
		Clear();
		//DestroyNode(Node_p node)
		//DestoryNode(_list);
		_list = NULL;
	}
	/*~List()
	{
		size_t size = Size();
		Destroy(Begin(),End());
		ListNodeAllocator::Deallocate(_list,size);
	}*/

	Iterator Begin() 
	{
		return _list->_next;
	}
	Iterator End() 
	{
		return _list;
	}
	ConstIterator Begin() const
	{
		return _list->_next;
		//return ConstIterator(_list->_next);
	}
	ConstIterator End() const
	{
		return _list->_next;
		//return ConstIterator(_list);
	}
	void PushBack(const T& data)
	{
		Insert(End(),data);
	}
	void PopBack()
	{
		Iterator tmp = End();
		Erase(--tmp);
	}
	void PushFront(const T& data)
	{
		Insert(Begin(),data);
	}
	void PopFront()
	{
		Erase(Begin());
	}
	//取头结点的内容(元素值)
	Reference Front()
	{
		return *Begin();
	}
	ConstReference Front()const
	{
	}
	Reference Back()
	{
		return *(--End());
	}
	ConstReference Back()const
	{
	}
	//在当前位置的前面插入
	void Insert(Iterator pos, const T& data)
	{
		Node_p cur = pos._node;
		Node_p prev = cur->_prev;
		//Node_p tmp = new Node(data);
		Node_p tmp = CreateNode(sizeof(Node),data);
		tmp->_next = cur;
		cur->_prev = tmp;
		prev->_next = tmp;
		tmp->_prev = prev;
	}
	Iterator Erase(Iterator pos)
	{
		Node_p cur = pos._node;
		Node_p prev = cur->_prev;
		Node_p next = cur->_next;
		prev->_next = next;
		next->_prev = prev;
		delete cur;
		return Iterator(next);
	}
	bool Empty()const
	{
		if (_list->_next == _list){
			return true;
		}
		else{
			return false;
		}
	}
	size_t Size()
	{
		/*size_t size;
		Distance(Begin(),End(),size);
		return size;*/
		int size = 0;
		Node_p start = _list->_next;
		Node_p end = _list;
		while (start != end){
			++size;
			start = start->_next;
		}
		return size;
	}
	void Clear()//All the elements in the list container are dropped
	{
		Iterator tmp = Begin();
		while (tmp != End()){
			//DestroyNode(*tmp);//error
			//DestroyNode(tmp._node);
			++tmp;
		}
		_list->_prev = _list;
		_list->_next = _list;
	}
	//assign函数用于重置list的内容
	//void assign(InputIterator first, InputIterator last);//用一段连续的空间重置
	//void assign(size_type n, const T& u);//用具体的值重置
	//void Remove(const T& x);
	//void Sort();
	//void Unique();
	//void Reverse();
	//void Merge(List<T,Alloc>& l);

	//接合函数,把以下内容接合到pos所指定的位置之前
	//一个链表的所有值
	//一个链表所指定的迭代器所指向的值
	//一个链表所指定的两个迭代器之间所指向的值
	//void Splice(Iterator pos,List<T,Alloc>& x);
	//void Splice(Iterator pos, List<T, Alloc>& x,Iterator it);
	//void Splice(Iterator pos, List<T, Alloc>& x,Iterator first,Iterator last);

	//Void Swap(List<T,Alloc>& l);

	//不支持随机访问,无[]重载
protected:
	Node_p _list;
};
#endif

Test.cpp

void printList1(List<int> l)
{
	List<int>::Iterator ite = l.Begin();
	*ite = 2;
	for (ite = l.Begin(); ite != l.End(); ++ite){
		std::cout << *ite << std::endl;
	}
}

void printList2(const List<int> l)
{
	List<int>::ConstIterator ite = l.Begin();
	//*ite = 2;
	for (ite = l.Begin(); ite != l.End(); ++ite){
		std::cout << *ite << std::endl;
	}
}

void TestList()
{
	/*std::list<aa> l1;
	std::list<aa>::iterator items;
	l1.push_back(aa());
	l1.push_back(aa(1, ‘b‘));
	l1.push_back(aa(2, ‘c‘));
	l1.push_back(aa(3, ‘d‘));
	items = l1.begin();

	for (; items != l1.end(); ){
		std::cout << items->_a << "  " <<items->_c <<std::endl;
		items++;
	}*/

	List<int> l;
	l.PushBack(1);
	l.PushBack(2);
	l.PushBack(3);
	l.PushBack(4);
	List<int>::Iterator ite;
	for (ite = l.Begin(); ite != l.End(); ++ite){
		std::cout << *ite << std::endl;
	}
	std::cout << l.Size() << std::endl;

	ite = l.Begin();
	l.Insert(ite,100);
	std::cout << *ite << std::endl;

	l.PopFront();
	l.PopBack();
	l.PushFront(78);
	l.PushFront(100);

	List<int>::Iterator it = l.Begin();
	List<int>::Iterator its = l.End();
	List<int>::Iterator item;
	std::cout<<*it<<std::endl;
	++it;
	its--;
	std::cout << (it != its) << std::endl;

	int data1 = l.Front();
	int data2= l.Back();
	std::cout<<l.Size()<<std::endl;
	std::cout << !l.Empty() << std::endl;

	//list<int> l;
	//l.PushBack(1);
	//l.PushBack(2);
	////printlist1(l);
	//printlist2(l);
}
时间: 2024-07-30 04:12:04

(四)STL剖析——List的相关文章

初识STL 剖析list部分源码

1.STL    库函数的设计第一位是通用性,模板为其提供了可能:标准模板库中的所有算法和容器都是通过模板实现的.  STL(标准模板库)是 C++最有特色,最实用的部分之一. STL整个架构模型如下: 2.list(双向循环链表) 调用STL系统的#include<list>,用系统的双向循环链表结构处理: #include<iostream> #include<list> //调用系统的list,双向循环链表结构 using namespace std; int m

(五)STL剖析——set、map

简单了解了set.map的框架和接口 set //所有元素都会根据键值进行排序,set不允许有两个相同的键值 //不能通过迭代器对set的元素进行修改,set的键值即实值,实值即键值,底层为const //set使用红黑树的insert_unique(),mutilset才能使用insert_equal() //关联式容器进行查找时最好使用其自己提供的find,而不是STL算法find template<class T1, class T2> struct Pair { T1 first; T

(一)STL剖析——空间配置器

Alloc.h //Alloc.h负责内存空间的配置与释放 //Construct.h负责对象内容的构造与析构 //这两个头文件在memory文件中包含 #pragma once typedef void(*HANDLER_FUNC)(); //一级空间配置器 template <int inst> class __MallocAllocTemplate  { public: static void* Allocate(size_t size)//静态成员函数 { void* result =

(二)STL剖析——迭代器

TypeTraits.h #pragma once //双底线前缀的意思是SGI内部所用的东西,不在STL标准之内 //IteratorTraits负责萃取迭代器的特性 //__TypeTraits负责萃取型别的特性 struct __FalseType {}; struct __TrueType {}; //一个类究竟什么时候该有自己的平凡类型构造 template<class T> struct __TypeTraits { typedef __FalseType HasTrivialDe

(三)STL剖析——Vector

Vector.h #pragma once #include "Alloc.h" #include "Uninitialized.h" #include <assert.h> //vector采用的数据结构就是线性连续空间 template<class T,class Alloc = alloc> class Vector { public: //嵌套型别 typedef T* Iterator; typedef T ValueType; t

内存管理_深入剖析volatile关键字

四.深入剖析volatile关键字 在前面讲述了很多东西,其实都是为讲述volatile关键字作铺垫,那么接下来我们就进入主题. 1.volatile关键字的两层语义 一旦一个共享变量(类的成员变量.类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的. 2)禁止进行指令重排序. 先看一段代码,假如线程1先执行,线程2后执行: //线程1 boolean stop =

剖析Qt的事件机制原理

版权声明 请尊重原创作品.转载请保持文章完整性,并以超链接形式注明原始作者“tingsking18”和主站点地址,方便其他朋友提问和指正. QT源码解析(一) QT创建窗口程序.消息循环和WinMain函数 QT源码解析(二)深入剖析QT元对象系统和信号槽机制 QT源码解析(三)深入剖析QT元对象系统和信号槽机制(续) QT源码解析(四)剖析Qt的事件机制原理 QT源码解析(五)QLibrary跨平台调用动态库的实现 QT源码解析(六)Qt信号槽机制与事件机制的联系 QT源码解析(七)Qt创建窗

Java并发编程:volatile关键字解析(转)

volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以重获生机. volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情.由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来了解一下与内存模型相关的概念和知识,然后分析了volatile关键字的实现原理,最后给出了几个使用vola

Java并发编程:volatile关键字解析

volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以重获生机. volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情.由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来了解一下与内存模型相关的概念和知识,然后分析了volatile关键字的实现原理,最后给出了几个使用vola