User Tools

Site Tools


in204:tds:sujets:td4:part2

This is an old revision of the document!


Partie II – Création d’itérateurs

TD4

Nous considérons un ensemble de nombres entiers correspondant à un interval fermé entre [minValue, maxValue] défini par la classe suivante :

class interval
{
private:
	int minValue;
	int maxValue;
 
public:
	typedef int value_type;
	typedef size_t size_type;
        typedef ptrdiff_t difference_type;
 
	interval(int theMinValue, int theMaxValue) : 
		minValue(theMinValue), maxValue(theMaxValue) 
	{}
	interval(const interval& anotherInterval):
		minValue(anotherInterval.minValue), 			 		  
                maxValue(anotherInterval.maxValue)
	{}
	interval& operator = (const interval& anotherInterval)
	{
		minValue = anotherInterval.minValue;
		maxValue = anotherInterval.maxValue;
		return *this;
	}
	size_type size() const
	{
		return (size_type)(maxValue - minValue);
	}
	int operator[](size_type anIndex) const
	{
		if (anIndex > size())
			throw std::out_of_range("Index out of range");
		return minValue + (int)anIndex;
	}
	bool operator == (const interval& anotherInterval) const
	{
		return anotherInterval.maxValue == maxValue &&
			anotherInterval.minValue == minValue;
	}
	bool operator != (const interval& anotherInterval) const
	{
		return anotherInterval.maxValue != maxValue ||
			anotherInterval.minValue != minValue;
	}
};

Nous souhaitons pouvoir définir des itérateurs pour pouvoir itérer sur cet interval. Pour ce faire, nous devons ajouter au moins les méthodes suivantes et champs suivants :

	friend class interval_iterator;
	typedef interval_iterator const_iterator;
	const_iterator begin() const noexcept;
	const_iterator end() const noexcept;

En supposant que la classe itérateur s’appelle interval_iterator. Il ne reste plus qu’à créer une classe interval_iterator dont le squelette serait le suivant :

class interval_iterator
	: public std::iterator <std::forward_iterator_tag, int>
{
private:
	friend class interval;
	const interval* mInterval; // Référence à l'interval.
	int mCurrent; // la valeur courante dont on fait référence.
 
	interval_iterator(const interval& anInterval, int aCurrentValue) : 
		mInterval(&anInterval), mCurrent(aCurrentValue) {}
 
public:
	interval_iterator(const interval_iterator& anotherIterator):
		mInterval(anotherIterator.mInterval),
		mCurrent(anotherIterator.mCurrent) {}
 
	interval_iterator& operator = (interval_iterator& anotherIterator)
	{
		mInterval = anotherIterator.mInterval;
		mCurrent = anotherIterator.mCurrent;
		return *this;
	}
 
	const reference operator*() const;
	const pointer operator->() const;
	interval_iterator& operator++();
	interval_iterator& operator++(int);
	bool operator ==(const interval_iterator&) const;
	bool operator !=(const interval_iterator&) const;
 
};

Question 1.0

Complétez les classes interval et interval_iterator afin de pouvoir supporter les itérateurs.

Correction

Correction

Nous débutons par compléter la classe interval. La classe 'interval doit exposer au moins deux méthodes que sont les méthodes : <code cpp> iterator begin(); Itérateur faisant référence au premier élément contenu dans le containeur iterator end(); Itérateur indiquant que l'on a dépassé le dernier élément de la séquence d'éléments contenus dans le containeur. </code> De plus nous devons définir aussi les types suivants: <code cpp> value_type le type des valeurs contenues dans le containeur. habituellement T reference un type faisant référence aux valeurs contenues dans habituellement T& const_reference un type faisant référence aux valeurs contenues dans mais empêchant la modification de ces valeurs, habituellement T& iterator iterateur faisant référence aux valeurs contenues dans le containeur permettant un accès en lecture et écriture de ces valeurs si l'accès en écriture est supportée par le containeur. const_iterator itérateur faisant référence aux valeurs contenues dans le containeur ne permettant qu'un accès en lecture. difference_type un type d'entier signé qui correspond à la distance entre deux itérateurs, size_type Un type d'entier non-signé qui correspond au type taille du containeur. </code> Dans le cas de notre classe interval, le type des valeurs est int, les valeurs ne peuvant pas être modifiées, ce qui induit les définitions suivantes : <code cpp> class interval { public: … typedef const int value_type; typedef reference const int&; typedef const_reference const int&; … }; </code> Pour la classe iterator, nous ne pouvons définir que des itérateurs ne pouvant pas modifier les valeurs contenues dans l'interval. Donc nous définissons les champs comme suit : <code cpp> class interval { public: … typedef interval_iterator iterator; typedef interval_iterator const_iterator; typedef ptrdiff_t difference_type; typedef size_t size_type; … }; </code> Il reste dés lors à définir les fonctions begin et end. Pour ce faire, nous définissons les fonctions comme suit : <code cpp> class interval { public: … inline iterator begin() const; inline iterator end() const; … }; class interval_iterator { }; inline interval::iterator interval::begin() const { return iterator(*this, minValue); } inline interval::iterator interval::end() const { return iterator(*this, maxValue + 1); } </code>
La fonction begin retourne un objet de type interval_iterator qui fait référence à l'interval courant et qui fait référence à minValue qui correspond à la première valeur de l'interval d'entier.
La fonction end retourne un objet de type interval_iterator qui fait référence à l'interval courant et qui fait référence à maxValue qui correspond à la valeur situé après la dernière valeur valide de l'interval, donc fait bien référence à la première valeur située en dehors de la séquence de valeur.
Les fonctions begin et end font appel à un constructeur de la classe interval_iterator. En C++, avant de pouvoir appeller un constructeur, il faut que la classe soit définie. Comme la classe interval_iterator est définie après la classe interval, il est nécessaire que le code des fonctions begin et end soit située après la classe interval_iterator. Il n'est pas possible de les définir dans le corps de la classe interval. </hidden> ===== Question 2.0 ===== Tester le bon fonctionnement de classe avec le code suivant :

in204/tds/sujets/td4/part2.1571133780.txt.gz · Last modified: 2019/10/15 10:03 by bmonsuez