6
2
2014
2

c++容器之迭代器

本文参考一下的博客:

http://blog.csdn.net/yxysdcl/article/details/5567460

 

迭代器实现了容器中对象的访问方法。迭代器就如同一个指针,其实指针也就是特殊的迭代器。下面看两个小例子帮助理解:

1.简单变量类型迭代器

一下是vector类型的简单实现

template <class T>
class vector {
private:
	T* pbegin;
	int n; //当前大小
public:
	vector() {
		pbegin = new T[100]; //暂时先固定大小
		n = 0;
	}
	
	T* begin() {
		return pbegin;
	}
	void insert(T d){
		pbegin[n++] = d;
	}
	typedef T* iterator; //vector的迭代器就是基础指针类型
};

vector是数组的实现,故由首地址可以知道后面元素的位置,故访问vector迭代器,其实就是基础指针,可以通过++,--操作

下面为测试操作

//测试vector
	vector<int> a;
	a.insert(1);
	a.insert(2);
	vector<int>::iterator itra;
	itra = a.begin();
	printf("%d/n", *itra); 
	itra++;
	printf("%d/n", *itra);
	itra--; //基础指针类型都支持++,--,+,-等操作符
	printf("%d/n", *itra);

2.链表类型的迭代器。

链表每个元素在不同位置,那怎么设计迭代器,使得它也可以通过++/--等操作实现定位呢?一下为例子

template <class T>
class List{
private:
	struct Node{ //链表的节点
		T data;
		Node* next;
	};
	Node* pbegin; //表头
	class List_iterator{ //链表的迭代器
		Node* cur; //当前指向
	public:
		void operator = (Node* ptr) {
			cur = ptr;
		}
		void operator ++ () {
			cur = cur->next;
		}
		// ...还可以重载-- + -等操作符
		T operator * (){
			return cur->data;
		}
	};
public :
	List() {
		pbegin=NULL;
	}
	Node* begin() {
		return pbegin;
	}
	void insert(T d) {
		Node* p=pbegin;
		while(p && p->next) p=p->next;
		Node* t = new Node;
		t->data = d;
		t->next = NULL;
		if(pbegin==NULL)
			pbegin = t;
		else
			p->next = t;
	}
	typedef List_iterator iterator; //List的迭代器是一个类
};

如上面代码,即对++操作进行了重载。测试代码如下

/测试List
	List<int> b;
	b.insert(1);
	b.insert(2);
	List<int>::iterator itrb;
	itrb = b.begin();
	printf("%d/n", *itrb);
	itrb++; // 该迭代器只支持++
	printf("%d/n", *itrb);

由此我们可以看出迭代器的目的,即通过迭代器,更方便的便利访问容器里的元素。这样在STL设计算法时,可以脱离容器设计更加通用的算法。如,容器中查找一个元素一般是遍历整个集合,如果没有迭代器,需要为vector和list设计两个查找算法。

总结;

模板:将算法和特定的数据类型分离

迭代器:将算法和特定的容器分离

Category: 面向对象 | Tags:
6
2
2014
26

关于模板解读

本文借鉴参考:

http://www.cnblogs.com/gaojun/archive/2010/09/10/1823354.html

1.概念

模板的好处:实现代码的重用。

如何实现?:把类型定义为参数。

下面举例说明好处。若返回a,b之间较大的数,由于a,b类型不确定,故可能要定义多个函数。如:

//函数1.

int max(int x,int y);
{return(x>y)?x:y ;}

//函数2.
float max( float x,float y){
return (x>y)? x:y ;}

//函数3.
double max(double x,double y)
{return (c>y)? x:y ;}

如果主函数调用max(a,b).而a、b是char类型的,则程序会出错。因为定义的三个类型中没有char的比较。于是就能用模板来解决这个问题

2.函数的模板

函数模板形式

Template<class T或者typename T>

返回值类型 函数名 (形参表)

{ //函数定义}

以下程序

#include <iostream>

using std::cout;

using std::endl;

//声明一个函数模版,用来比较输入的两个相同数据类型的参数的大小,class也可以被typename代替,

//T可以被任何字母或者数字代替。

template <class T>

T min(T x,T y)

{ return(x<y)?x:y;}

void main( )

{

     int n1=2,n2=10;

     double d1=1.5,d2=5.6;

     cout<< "较小整数:"<<min(n1,n2)<<endl;

     cout<< "较小实数:"<<min(d1,d2)<<endl;

     system("PAUSE");

}

这样就可以通过模板将函数定义一次。

3.类模板

定义一个类模板:

Template(class T或者typename T)

class 类名{

//类定义};

看如下例子

// ClassTemplate.h
#ifndef ClassTemplate_HH

#define ClassTemplate_HH

template<typename T1,typename T2>

class myClass{

private:

     T1 I;

     T2 J;

public:

     myClass(T1 a, T2 b);//Constructor

     void show();

};

//这是构造函数

//注意这些格式

template <typename T1,typename T2>

myClass<T1,T2>::myClass(T1 a,T2 b):I(a),J(b){}

//这是void show();

template <typename T1,typename T2>

void myClass<T1,T2>::show()

{

     cout<<"I="<<I<<", J="<<J<<endl;

}

#endif

// Test.cpp

#include <iostream>

#include "ClassTemplate.h"

using std::cout;

using std::endl;

void main()

{

     myClass<int,int> class1(3,5);

     class1.show();

     myClass<int,char> class2(3,'a');

     class2.show();

     myClass<double,int> class3(2.9,10);

     class3.show();

     system("PAUSE");

}

 

Category: 面向对象 | Tags:

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com