Vous êtes sur la page 1sur 5

UNIVERSITE DE LA MANOUBA ANNEE UNIVERSITAIRE

-----¤¤¤¤----- 2010-2011
ECOLE NATIONALE DES SCIENCES
DE L'INFORMATIQUE

Solutionnaire de l’exercice3 de l’examen 1er semestre


(Session principale – Janvier 2011)
Matière : Conception et Programmation Orientées Objets Date : vendredi 7 janvier 2011
Niveau : II2 Durée: 2H
Enseignants : Y. JAMOUSSI, I. BEN HAMOUDA, S.MTIBAA, I.FLISS Documents : non autorisés

Exercice n°3 : (STL)


Question 3.1 (1 pt)
Pour le choix du conteneur de points, on hésite entre les options suivantes : vector, list, set
(voir annexe). Supposons que dans notre application, les points seront ajoutés, retirés et
modifiés fréquemment. Dites quel conteneur est le plus approprié dans ce contexte (justifiez
votre choix) et ajoutez la déclaration de ce conteneur à l’interface de la classe.
Solution :

Une liste est préférable parce que l'ajout, le retrait et la modification se


font efficacement. De plus un multiset n'est pas acceptable parce que
l'ordre des points doit être conservé.

list<Point> points;

Question 3.2 (1 pt)


Avec le conteneur que vous avez choisi, implémenter les méthodes ajouterPoint et
retirerPoint. (N.B. : le polygone comporte que des points distincts (pas de superposition de
points)).
Solution :

void Polygone::ajouterPoint(double x, double y)


{
points.push_back(Point(x,y));
}

void Polygone::retirerPoint(double x, double y)


{
list<Point>::iterator it =
find(points.begin(), points.end(), Point(x,y));
if (it != points.end())
points.erase(it);
}
Question 3.3 ( 2,5 pts)
On se rend compte que nous allons avoir à modifier tous les points d'un polygone. Ayant bien
compris la STL, un développeur implémente la fonction appliquer() qui peut appliquer
une opération sur tous les points en recevant une fonction ou un foncteur approprié. Il ajoute
donc ce code à la définition de la classe Polygone :
template<typename FONCT>
void appliquer(FONCT f){
for_each(points.begin(), points.end(), f);
}
Votre partie du travail consiste à implémenter une fonction ou un foncteur pour chacune des
trois opérations suivantes :
a) Permuter les coordonnées des points (cad : x dans y et y dans x).
b) Déplacer les points d'un delta vecteur <u ,v>, (u et v des variables entières).
c) Etirer le polygone suivant la loi suivante : si l’abscisse du 1er point du polygone
est inférieure à 20 alors déplacer ce point par <1,1> sinon déplacer par <-1,-1>.
Garder le même déplacement pour les quatre points suivants. Refaire le même
raisonnement pour le 5ème point, 10ème point, etc.

Solution :

void permuter(Point & p)


{
p = Point(p.getY(), p.getX());
}

class FoncteurDeplacer {
public:
FoncteurDeplacer(double x, double y) : u(x), v(y) {}
void operator()(Point& p) const {
p = Point(p.getX() + u, p.getY() + v);
}
private:
double u, v;
};

class FoncteurEtirer {
public:
FoncteurEtirer() {i=1;}
void operator()(Point& p) const {
if (i++ % 5 ==1) if (p.getX() < 20) delta =1 ; else delta=-1 ;
p = Point(p.getX() + delta, p.getY() + delta);
}
private:
int i , delta ;
};

Question 3.4 ( 2 pts)


Sachant qu’on dispose d’un polygone formé des points suivants : <1,2>, <3,6>, <3,15>,
<5,8>, <6,12>, <7,15>.
a) Donner la partie du programme principal qui assure :
i. La création du polygone en question
ii. La permutation (conformément à la question 3.3 a)
iii. Le déplacement des points du polygone d’un delta vecteur = <5,5>
(conformément à la question 3.3 b)
iv. L’étirement (conformément à la question 3.3 c)

Solution :

void main() {

Polygone p;

p.ajouterPoint(1,2);
p.ajouterPoint(3,6);
p.ajouterPoint(3,15);
p.ajouterPoint(5,8);
p.ajouterPoint(6,12);
p.ajouterPoint(7,15);

p.appliquer(permuter);

p.appliquer(FoncteurDeplacer(5,5));

p.appliquer(FoncteurEtirer());

b) Donner les coordonnées des points du polygone après l’étirement (et ce avant la fin du
programme) :
Solution :

8,7 - 12,9 - 21,9 - 14,11 - 18,12 - 19,11

Question 3.5 ( 2 pts)


Sachant que la suppression (resp. l’ajout) d’un point inexistant (resp. un point existant)
déclenche un traitement exceptionnel. A cet effet, un développeur a décidé de gérer les
exceptions par une solution objet. Ainsi, il a proposé une ébauche de trois classes (à gauche)
et il a ajouté entre chaque appel d’ajout et appel de suppression un bloc try/catch (à droite)
comme suit :
class Pb {
virtual FaireNecessaire(){} try {
}; // suppression ou ajout
}
class PbSuppression : public Pb { }; catch (Pb & e)
e->FaireNecessaire();
class PbAjout : public Pb { };

a) La suppression d’un point inexistant déclenche l’affichage d’un message d’erreur sur
la console d’erreur (cerr). Donner la classe PbSuppression (déclaration+corps)
Solution :

class PbSuppression {
Point p;
public :
PbSuppression(Point & p) : p(p) { } // ou sans arg
FaireNecessaire() {
cerr << "Message d’erreur" << endl;
// ou
cerr << "Le point (" << p.getX() << "," << p.getY()
<< ") est inexistant" << endl;
}};

b) Donner le nouveau corps de la méthode void Polygone::retirerPoint(double,double)


incluant le lancement d’exception.
Solution :

void Polygone::retirerPoint(int x,int y) {


list<Point>::iterator it = find(points.begin(), points.end(),
Point(x,y));
f (it != points.end()) points.erase(it);
else throw PbSuppression ();
// ou throw PbSuppression(Point(x,y));

c) L’ajout d’un point M(x,y) existant déclenche l’ajout d’un point M1(x1+1,y). [x1 est la
plus grande abscisse des points du polygone]. Sans faire le calcul de x1, donner la
classe PbAjout (déclaration+corps).
Solution :

class PbAjout {
Polygone * p;
int x1,y1;
public :
PbAjout(Polygone * pol, int y) {
pol;
y1 = y;
}

[ int X1() { // chercher le max des abscisses dans p } ]

FaireNecessaire() {

p->ajouterPoint(x1 +1 , y1);

};
d) Donner le nouveau corps de la méthode void Polygone::ajouterPoint(int,int) incluant
le lancement d’exception.

Solution :

void Polygone::ajouterPoint(int x, int y) {

list<Point>::iterator it =
find(points.begin(), points.end(), Point(x,y));

if (it = points.end()) points.push_back(Point(x,y));


else throw PbAjout (this, y);

Vous aimerez peut-être aussi