Choisissez votre style : colorisé, impression

Correction
Série Notée (Bonus)
Sujet 1


Note: 15 points sur 80 étaient facultatifs.

Exercice 1 : Bases de la POO, Héritage, Polymorphisme

Quelques remarques (suite à des erreurs/maladresses dans les copies):

... et voici donc enfin un codage possible :

#include <iostream>
#include <string>
#include <cmath>

using namespace std;

const int MAX_X(100);
const int MAX_Y(100);
const int MEETING_RADIUS(3);

/* Une classe pour représenter les animaux
 *
 */

class Animal{
public:
    Animal(int x, int y);

    int get_x() const ;
    int get_y() const;

    void right(unsigned int);
    void left(unsigned int);
    void up(unsigned int);
    void down(unsigned int);

	// il est mieux de la definir en virtuelle pure
	// car on ne sait pas a ce stade qui va etre un predateur
	// ou une proie
	virtual bool isPrey() const = 0;
	virtual string getName() const {return "Animal";};
	
	void setSick(bool sick_)
		{
			sick = sick_;
		}
	
	void die()
		{
			dead = true;
		}
	
	bool isSick() const 
		{
			return sick;
		}
	bool isDead() const 
		{
			return dead;
		}

	// methode virtuelle pure
	// gerant les interactions entre animaux
	virtual void meet(Animal*) = 0;

	//teste si deux animaux peuvent interagir
	bool canMeet(Animal*) const;
	
	double distanceTo(const Animal&) const;
    
protected:
    int x;
    int y;
	bool sick;
	bool dead;
};

/* Une sous-classe pour les proies
 */
class Prey : public Animal {
public:
    Prey(int x, int y);
	bool isPrey() const {
		return true;
	}

	string getName() const 
		{
			return "Proie";
		}
	
    void meet(Animal*);
};

/* Une sous-classe pour les predateurs
 */
class Predator : public Animal{
public:
    Predator(int x, int y);
	bool isPrey() const {return false;
	}
	
    void meet(Animal*);

	string getName() const 
		{
			return "Predateur";
		}
};



Animal::Animal(int x_, int y_) : x(x_), y(y_), sick(false), dead(false)
{
    // Attention aux conditions limites
	if(x > MAX_X) x = MAX_X;
	if(x < 0) x = 0;
	if(y > MAX_Y) y = MAX_Y;
	if(y < 0) y = 0;
}


int Animal::get_x() const {
    return x;
}

int Animal::get_y() const{
    return y;
}

void Animal::right(unsigned int units){
    x += units;
    if(x > MAX_X) x = MAX_X;
}

void Animal::left(unsigned int units){
    x -= units;
    if(x < 0) x = 0;
}

void Animal::up(unsigned int units){
    y += units;
    if(y > MAX_Y) y = MAX_Y;
}

void Animal::down(unsigned int units){
    y -= units;
    if(y < 0) y = 0;
}

// calcule la distance d'un animal a un autre
double Animal::distanceTo(const Animal& otherAnimal) const {
    return sqrt(pow((x-otherAnimal.get_x()),2) + pow((y-otherAnimal.get_y()),2));
}

// pour un affichage polymorphique : on utilise la virtualit'e des methodes
// appel'ees
ostream& operator<<(ostream& out, Animal& animal){
    out << animal.getName() << " en ("<< animal.get_x() << ',' << animal.get_y() << ')';
	if (animal.isDead())
		out << ": animal mort";
	else 
		if (animal.isSick())
			out << ": animal malade";
	    else
			out << ": animal sain";
	return out;
}

Prey::Prey(int x, int y) : Animal(x,y){}


bool Animal::canMeet(Animal* otherAnimal) const
{
	
	return (!isDead() && !(otherAnimal->isDead()) &&
			distanceTo(*otherAnimal) <= MEETING_RADIUS);
}


void Prey::meet(Animal* otherAnimal){
	if (canMeet(otherAnimal))
		{
			if (!otherAnimal->isPrey() &&  !isSick())
			{
				die();
			}
		}
}

Predator::Predator(int x, int y) : Animal(x,y) {}

void Predator::meet(Animal* otherAnimal){
	if (canMeet(otherAnimal))
	{
		if (otherAnimal->isPrey() && !otherAnimal->isSick())
		{
			otherAnimal->die();
		}
	}
}

//PROGRAMME PRINCIPAL (fourni)
int main(){
	/* TEST1 
	 */
    cout << "Test de la partie 1 :" <<endl;
	cout << "--------------------" << endl;
	Animal* animal1(new Predator(0,0));
	Animal* animal2(new Prey(25,0));
	Animal* animal3(new Predator(10000,100000));
	Animal* animal4(new Prey(-200,100000));
	cout << *animal1 << endl;
	cout << *animal2 << endl;

	cout << "Distance : ";
	cout << animal1->distanceTo(*animal2) << endl;
	
	cout << *animal3 << endl;

	cout << *animal4 << endl;
	animal1->setSick(true);
	cout << *animal1 << endl;

	animal1->up(10000);
	cout << *animal1 << endl;

	animal1->left(200);
	cout << *animal1 << endl;

	animal1->die();

	cout << *animal1 << endl;


	delete animal1;
	delete animal2;
	delete animal3;
	delete animal4;
	/*FIN TEST 1*/

	
	/* TEST2 */
	cout << endl;
	cout << "Test de la partie 2:" <<endl;
	cout << "--------------------" << endl;
		cout << "Proie saine, Predateur trop eloignes :" << endl;
	animal1 = new Prey(0,0);
	animal2 = new Predator(5,5);
	cout << *animal1 << endl;
	cout << *animal2 << endl;
	cout << "apres tentative de rencontre : " << endl;
	animal1->meet(animal2);
	cout << *animal1 << endl;
	cout << *animal2 << endl;
	cout << endl;

	cout << "Proie malade, Predateur se rencontrent :" << endl;
	animal1->setSick(true);
	animal2->left(4);
	animal2->down(4);
	cout << *animal1 << endl;
	cout << *animal2 << endl;
	cout << "apres rencontre  (dans les deux sens): " << endl;
	animal1->meet(animal2);
	cout << *animal1 << endl;
	cout << *animal2 << endl;
	animal2->meet(animal1);
	cout << *animal2 << endl;
	cout << *animal1 << endl;

	cout << endl;

	
	cout << "Proie saine, Predateur se rencontrent :" << endl;
	animal1->setSick(false);
	animal2->setSick(false);
	cout << *animal1 << endl;
	cout << *animal2 << endl;
	cout << "apres rencontre :" << endl;
	animal1->meet(animal2);
	cout << *animal1 << endl;
	cout << *animal2 << endl;
	cout << endl;
	
	
	
	cout << "Predateur, Proie saine  se rencontrent :" << endl;
	animal3 = new Prey(2,2);
	cout << *animal2 << endl;
	cout << *animal3<< endl;
	cout << "apres rencontre :" << endl;
	animal2->meet(animal3);
	cout << *animal2 << endl;
	cout << *animal3 << endl;
	cout << endl;
	
	delete animal1;
	animal1 = 0;
	delete animal2;
	animal2 = 0;
	delete animal3;
	animal3 = 0;
	
	cout << "Deux proies saines de rencontrent:" << endl;
	animal1 = new Prey(20,20);
	animal2 = new Prey(10,10);

	animal2->up(8);
	animal2->right(8);
	cout << *animal1 << endl;
	cout << *animal2 << endl;
	cout << "apres rencontre : " << endl;
	animal1->meet(animal2);
	cout << *animal1 << endl;
	cout << *animal2 << endl;
	cout << endl;
	

	delete animal1;
	animal1 = 0;
	delete animal2;
	animal2 = 0;

	cout << "Deux predateurs se rencontrent:" << endl;
	animal1 = new Predator(20,20);
	animal2 = new Predator(10,10);

	animal2->up(8);
	animal2->right(8);
	cout << *animal1 << endl;
	cout << *animal2 << endl;
	cout << "apres rencontre :" << endl;
	animal1->meet(animal2);
	cout << *animal1 << endl;
	cout << *animal2 << endl;
	
	delete animal1;
	animal1 = 0;
	delete animal2;
	animal2 = 0;
	/* FIN TEST2*/
	return 0;
}


Exercice 2: durée de vie des variables

#include <iostream>
#include<vector>
#include<string>

using namespace std;

class Composant
{
public:
	Composant(string nom, double quantite)
		:nom_(nom), quantite_(quantite)
		{}
	void afficher(ostream& out) const
		{
			out << nom_ << " " << quantite_ << endl;
		}
	
private:
	string nom_;
	double quantite_;
};


class Dosage : public vector<Composant*>
{
public:
	/*
	 * le probleme est du au fait que cette methode ajoute au vecteur
	 * l'adresse d'une variable locale.
	 * Cette variable etant detruite a la fin de l'execution de la methode
	 * le pointeur stock'e dans la collection sera invalide
	 */
	 
	void ajouter_composant(string nom, double quantite)
		{
			Composant c(nom, quantite);
			  push_back(&c);
			  
			  /* Solution: allocation dynamique
			push_back(new Composant(nom,quantite));
			  */
		}
	void afficher(ostream& out) const
		{
			for (int i(0); i < size(); ++i)
				(*this)[i]->afficher(out);
		}
	
	void vider() 
		{
				for (int i(0); i < size(); ++i)
					delete (*this)[i];
				clear();
		}
	
};

int main()
{
	Dosage d;
	d.ajouter_composant("alcool", 0.3);
	d.ajouter_composant("formol", 0.4);
	d.afficher(cout);
	d.vider();
	
	return 0;

}