3.2 Le fichier PIterator_impl.h

L'include de base :

1
2
3
4
5
6
7
8
9
10
11
#ifndef __PITERATOR_IMPL_H__
#define __PITERATOR_IMPL_H__

#include "PIterator.h"






#endif

Les constructeurs et le destructeur :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template <class T>
PIterator<T>::PIterator(){
	p_element = NULL;
}

template <class T>
PIterator<T>::PIterator(PElement<T>* element){
	p_element = element;
}

template <class T>
PIterator<T>::PIterator(const PIterator<T> & it){
	copyPIterator(it);
}

template <class T>
PIterator<T>::~PIterator(){}

L'opérateur = :

1
2
3
4
5
template <class T>
typename PIterator<T>::PIterator & PIterator<T>::operator = (const PIterator<T> & it){
	copyPIterator(it);
	return *this;
}

C'est quoi le typename PIterator:: devant le PIterator retourné ?

C'est parce que le type PIterator n'existe pas, enfin pas vraiment comme il est définit à un type près. Donc on met un typename PIterator:: pour définir le type.

les opérateurs += et -= :

1
2
3
4
5
6
7
8
9
10
11
template <class T>
typename PIterator<T>::PIterator & PIterator<T>::operator += (int nb){
	next(nb);
	return *this;
}

template <class T>
typename PIterator<T>::PIterator & PIterator<T>::operator -= (int nb){
	prev(nb);
	return *this;
}

ils vont permettre de déplacer l'itérateur de plusieurs PElement en un seul appel.

Les opérateurs ++ et -- à gauche et à droite :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
template <class T>
typename PIterator<T>::PIterator & PIterator<T>::operator ++ (){
	next();
	return *this;
}

template <class T>
typename PIterator<T>::PIterator & PIterator<T>::operator ++(int nb){
	next();
	return *this;
}

template <class T>
typename PIterator<T>::PIterator & PIterator<T>::operator -- (){
	prev();
	return *this;
}

template <class T>
typename PIterator<T>::PIterator & PIterator<T>::operator -- (int nb){
	prev();
	return *this;
}

Pourquoi on n'utilise pas le nb que l'on passe en paramètre.

Je vous l'ai dit au tout début du cours (ça fait longtemps je vous l'accorde), dans le point sur les opérateurs. Le int est là pour différencier le ++ et le -- de droite, de ceux de gauche.

L'opérateur -&gt;

1
2
3
4
5
template <class T>
T* PIterator<T>::operator -> () const{
	if(p_element == NULL) return NULL;
	return &(p_element->p_data);
}

Là, il ne faut pas s'embrouiller avec le * et le &.

L'opérateur *

1
2
3
4
template <class T>
T & PIterator<T>::operator* () const{
	return p_element->p_data;
}

Notez que le type T n'a pas besoin de typename, car il est définit avec template <class T>

Les fonctions pour faire avancer et reculer le PIterator :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
template <class T>
void PIterator<T>::next(){
	if(p_element == NULL) return;
	p_element = p_element->p_next;
}

template <class T>
void PIterator<T>::next(int nb){
	for(int i(0); i < nb; i++) next();
}

template <class T>
void PIterator<T>::prev(){
	if(p_element == NULL) return;
	p_element = p_element->p_prev;
}

template <class T>
void PIterator<T>::prev(int nb){
	for(int i(0); i < nb; i++) prev();
}

Et enfin la fonction de copie :

1
2
3
4
template <class T>
void PIterator<T>::copyPIterator(const PIterator<T> & it){
	p_element = it.p_element;
}

il faudra donc que le type de l'élément ai un opérateur =.

Le fichier PIterator_impl.h une fois fini :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#ifndef __PITERATOR_IMPL_H__
#define __PITERATOR_IMPL_H__

#include "PIterator.h"

template <class T>
PIterator<T>::PIterator(){
	p_element = NULL;
}

template <class T>
PIterator<T>::PIterator(PElement<T>* element){
	p_element = element;
}

template <class T>
PIterator<T>::PIterator(const PIterator<T> & it){
	copyPIterator(it);
}

template <class T>
PIterator<T>::~PIterator(){}

template <class T>
typename PIterator<T>::PIterator & PIterator<T>::operator = (const PIterator<T> & it){
	copyPIterator(it);
	return *this;
}

template <class T>
typename PIterator<T>::PIterator & PIterator<T>::operator += (int nb){
	next(nb);
	return *this;
}

template <class T>
typename PIterator<T>::PIterator & PIterator<T>::operator -= (int nb){
	prev(nb);
	return *this;
}

template <class T>
typename PIterator<T>::PIterator & PIterator<T>::operator ++ (){
	next();
	return *this;
}

template <class T>
typename PIterator<T>::PIterator & PIterator<T>::operator ++(int nb){
	next();
	return *this;
}

template <class T>
typename PIterator<T>::PIterator & PIterator<T>::operator -- (){
	prev();
	return *this;
}

template <class T>
typename PIterator<T>::PIterator & PIterator<T>::operator -- (int nb){
	prev();
	return *this;
}

template <class T>
T* PIterator<T>::operator -> () const{
	if(p_element == NULL) return NULL;
	return &(p_element->p_data);
}

template <class T>
T & PIterator<T>::operator* () const{
	return p_element->p_data;
}

template <class T>
void PIterator<T>::next(){
	if(p_element == NULL) return;
	p_element = p_element->p_next;
}

template <class T>
void PIterator<T>::next(int nb){
	for(int i(0); i < nb; i++) next();
}

template <class T>
void PIterator<T>::prev(){
	if(p_element == NULL) return;
	p_element = p_element->p_prev;
}

template <class T>
void PIterator<T>::prev(int nb){
	for(int i(0); i < nb; i++) prev();
}

template <class T>
void PIterator<T>::copyPIterator(const PIterator<T> & it){
	p_element = it.p_element;
}

#endif

Passons à la classe PList.