﻿POUPA Adrien, BUOB Edgar								Efrei L'3

					TP N°7

_Introduction_

* Quel mécanisme important des langages de programmation objet va-t-on utiliser et comment peut-on le
mettre en œuvre en C++ ?

	On va utiliser le polymorphisme via le système d'héritage de C++.
	On ne se sert pas des templates dans ce TP.


_Première partie_

__Classe "Expression"__

* Que peut-on dire de la méthode  eval de la classe "Expression" ?

	Cette méthode est virtuelle pure car "= 0" à la fin de la déclaration de la méthode.

* Qu’est-ce que cela implique pour la classe "Expression" ?

	On ne peut pas instancier la classe "Expression"; seulement utiliser des pointeurs ou des références vers elle.

* Comment appelle-t-on ce genre de classe ?

	Une classe qui comporte au moins une méthode virtuelle pure est dite "classe abstraite".

* Expliquez ce que permet de faire l’attribut  _pool ?

	Le pool est un gestionnaire de ressources rudimentaire; il permet de
	- compter et enregistrer les adresses de toutes les instances "en vie"
	- retrouver l’adresse d’une instance par son nom
	- libérer toutes les instances qui ne l’ont pas été à la fin du programme

* Est-ce un attribut d’instance ou un attribut de classe ?

	C'est un attribut de classe.

* Que fait le constructeur de la classe "Expression" ?

	Expression(const string& nom) enregistre dans le pool l'instance actuelle.

* Que fait son destructeur ?

	virtual ~Expression() libère l'instance actuelle du pool.

* Pourquoi le destructeur de la classe "Expression" est-il  virtual ?

	Puisque la classe ne peut être instanciée, étant donnée qu'elle est abstraite, elle est
	destinée à être utilisée polymorphiquement, c'est-à-dire utilisée en place d'un objet de la classe mère.

	On veut utiliser le destructeur de la classe instanciée.

	Il faut donc être sûr que le bon destructeur sera appelé, d'où le "virtual".

* De quel type est la méthode "toutLiberer" ?

	static void toutLiberer() : fonction statique ne retournant rien, pas liée à un objet.
	Elle ne peut donc accéder à d'autres membres d'instances de la classe sinon les membres statiques.

* Quel est son rôle ?

	Elle applique itérativement l'operateur delete au premier élément du pool tant que le pool n’est pas vide.

* Quand sera-t-elle certainement appelée dans le programme principal ?

	Elle sera sûrement appelée à la fin du programme principal.

* La fonction "friend ostream& operator<<(ostream&, const Expression&)" est-elle une méthode de la
classe "Expression" ?

	La fonction est amie: sans faire partie directement de la classe "Expression", elle a accès
	à tous ses attributs.

* Cette dernière ne pouvant pas être instanciée, à quoi sert cette fonction ?

	Elle sert de moule, de cadre aux autres fonctions. Ainsi, on peut appeler un objet constante, cos ou sin
	sans savoir précisément duquel il s'agit en le désignant via "Expression".

* Quel est le nom ( _nom ) donné à une instance de la classe "Constante" ?

	On aura _nom = val avec Constante(double val) puisque "Constante" hérite de "Expression"
	C'est à dire Constante(3.0) => _nom = 3.0

__Classe "Unaire"__

* Décrire exactement ce que fait la méthode "str()" de la classe "Unaire".

	str() retourne une chaîne telle que "cos(exp)" ou "exp(sin)" à partir des deux
	arguments pris par le constructeur.

* Dessiner le diagramme de classes du fichier "expression.h". Faites ressortir les classes abstraites.

	Expression abstraite
		Constante
		Unaire abstraite
			Cos
			Sin

	Une tabulation = héritage de la classe au-dessus

__Synthèse__

* Quelle est la sortie standard obtenue par l’exécution du programme principal suivant ?

	Premiere partie
	enregistrer 1.0472
	enregistrer cos
	cos(1.0472) = 0.5
	liberer cos
	liberer 1.0472


_Deuxième partie_

* Quelle est la sortie standard obtenue par l’exécution du programme principal suivant ?

	Deuxieme partie
	(1 + (2 * sin(0.523599))) = 2
	((1 + (2 * sin(0.523599))) > 1.8) = 1


_Troisième partie_

* Pourquoi stocker la valeur d’une variable dans un attribut d’instance de la classe Variable pose problème et
ne constitue pas une bonne solution ?

	Si on fait cela, on casse le lien entre le nom d'une variable et sa valeur dans le tableau associatif,
	comme c'est expliqué dans la question suivante.

* Expliquez ce que permet de faire l’attribut de classe  _memoire ?

	_memoire permet le stockage des variables sous la forme d'un tableau associatif
	dont la clé est le nom de la variable et la valeur sa valeur. On a
	_memoire[nomVariable] = valeurVariable

* De quel type est la méthode  effacerMemoire ? Quel est son rôle ? Quand sera-t-elle certainement appelée
dans le programme principal ?

	static void effacerMemoire() : fonction statique ne retournant rien, pas liée à un objet.
	Elle ne peut donc accéder à d'autres membres d'instances de la classe sinon les membres statiques.
	Elle sera sûrement appelée à la fin du programme principal.

* Décrire en détail ce que fait la méthode  eval()  de la classe  Affectation . Quelle est la valeur retournée ?

	eval() affecte à une variable une valeur, puisqu'on affecte à _opleft la valeur (->eval) de _opright, en appelant
	la fonction set de la classe Variable
	Est retournée la valeur insérée, c'est à dire la valeur de op_right (_opright->eval()).

* Quelle est la sortie standard obtenue par l’exécution du programme principal suivant ?

	Troisieme partie
	x = 3
	y = 0
	(y <- (1 + (2 * x))) = 7
	y = 7
	y = 0


* Représentez graphiquement l’état en mémoire de l’expression  *a ainsi que l’état de l’attribut de classe 
_memoire lors de l’exécution du programme précédent, juste avant l’appel de  Variable::effacerMemoire();

	_memoire[x] = 0
	y <- (1 + (2 * x))
	y <- (1 + (2 * 3))
	y <- (1 + 6)
	y <- 7
	_memoire[y] = 7


_Quatrième partie_

	Cf Conditionnel.h et Conditionnel.cpp


_Cinquième partie_

* Analysez la classe  Pour du fichier  boucle.h en annexe. Décrivez ce que fait la fontion eval de cette classe ?

	Elle permet de calculer la valeur de l'expression donnée calc
	tant que la condition d'arrêt _cond n'est pas atteinte (soit != 0).

* Dessinez l’arbre correspondant à une expression qui affecte la factorielle d’une variable x
(dont la valeur a été affectée précédemment) à une variable y.

On a y <- x!

Par exemple, si x = 3, y <- 3! <=> y <- 1*2*3 <=> y <- 6

Soit

	    <-
	  /    \
	y	*
       	      /   \
	     1	    *
		  /   \
		2	*
			|
			3
					
On peut généraliser à y <- x! soit:

	    <-
	  /    \
	y	    *
		  /   \
		1	    *
			  /   \
			2     ...
				\
				 *
				 |
				 x

* Ecrivez le programme principal qui construit un tel arbre en mémoire et évalue l’expression pour x=3.0
puis x=5.0.

	J'obtiens une boucle infinie.
	J'ai du me tromper dans les initialisations
	Pourtant, la logique ne me semble pas fausse:
           On stocke le résultat dans y
           i est la variable d'incrémentation initialisée à 3
           à chaque tour, i = i-1 pour rencontrer la condition d'arrêt i = 0
           à chaque tour, y reçoit x*(x+1)

	Dans ces conditions, il est difficile d'aller plus loin dans le TP.