Université de Nice-Sophia Antipolis POLYTECH
ELEC4 2020–2021
Examen de Programmation C++
Durée : 1h
Aucun document autorisé
Mobiles interdits Nom : Prénom :
Au vu de la situation Covid19, Amoozom promeut l’achat de cadeaux en ligne pour la nouvelle année, avec pour certains, des taux de réduction attractifs.
Son catalogue propose des produits : des Pulls de couleurs diverses et des boîtes Leggoo variées pour tous les âges !
L’application à écrire comporte (dans un premier temps) 4 classes, données par le diagramme de classes suivant :
Dans ce diagramme, les # devant les variables indiquent qu’elles sont pro- tégées et les + devant les méthodes indiquent qu’elles sont publiques. En- fin, les flèches entre les classes Pull et Leggoo d’une part, et Produit d’autre part, indiquent des liens d’héritage (relation est-un). Enfin, la flèche terminée par un losange indique une relation d’agrégation entre les classes Produit et ListeDeCourses:i.e.une liste de courses possède des produits (relationa-un).
Classes Produit, Pull et Leggo
I 1. Écrivez en C++ les classesProduit,PulletLeggoodonnées par le diagramme précédent. Vous ajouterez la surcharge de l’opérateur << pour écrire un pro-
duit (avec le taux de réduction, s’il y a lieu) dans unstd::ostream. Pour cette dernière,attention à bien factoriser le code entre les différentes classes.
c l a s s P r o d u i t { p r o t e c t e d:
d o u b l e p r i x ;
d o u b l e t a u x R e d u c t i o n = 1 . 0 ;
std :: s t r i n g p r i x T o S t r i n g () c o n s t { std :: o s t r i n g s t r e a m s ;
i f (t h i s- > g e t T a u x () != 1 . 0 ) s < < " s o l d é à "; s < < t h i s- > g e t P r i x () < < " e u r o s ";
r e t u r n s . str ();
} p u b l i c:
P r o d u i t (c o n s t d o u b l e p ) : p r i x ( p ) {}
d o u b l e g e t P r i x () c o n s t { r e t u r n t h i s- > p r i x * g e t T a u x ();
}
d o u b l e g e t T a u x () c o n s t { r e t u r n t h i s- > t a u x R e d u c t i o n ; }
v o i d s e t T a u x (c o n s t d o u b l e t ) { t h i s- > t a u x R e d u c t i o n = t ; }
// toString méthode abstraite !
v i r t u a l std :: s t r i n g t o S t r i n g () c o n s t =0;
f r i e n d std :: o s t r e a m &o p e r a t o r< <( std :: o s t r e a m & f , c o n s t P r o d u i t & p ) {
r e t u r n f < < p . t o S t r i n g ();
} };
#i n c l u d e " P r o d u i t . hpp "
c l a s s P u l l : p u b l i c P r o d u i t { p r o t e c t e d:
std :: s t r i n g c o u l e u r ; p u b l i c:
P u l l (c o n s t d o u b l e p , c o n s t std :: s t r i n g c ) : P r o d u i t ( p ) , c o u l e u r ( c ) {}
std :: s t r i n g g e t C o u l e u r () c o n s t { r e t u r n c o u l e u r ;
}
v i r t u a l std :: s t r i n g t o S t r i n g () c o n s t o v e r r i d e { std :: o s t r i n g s t r e a m s ;
s < < " P u l l - " < < t h i s- > c o u l e u r < < " - "; s < < P r o d u i t :: p r i x T o S t r i n g ();
r e t u r n s . str ();
} };
#i n c l u d e " P r o d u i t . hpp "
c l a s s L e g g o o : p u b l i c P r o d u i t { p r o t e c t e d:
i n t age ; p u b l i c:
L e g g o o (c o n s t d o u b l e p , c o n s t i n t a =6) : P r o d u i t ( p ) , age ( a ) {}
i n t g e t A g e () c o n s t { r e t u r n t h i s- > age ; }
v i r t u a l std :: s t r i n g t o S t r i n g () c o n s t o v e r r i d e { std :: o s t r i n g s t r e a m s ;
s < < " L e g g o o - p o u r â g e s " < < t h i s- > g e t A g e () < < " + - "; s < < P r o d u i t :: p r i x T o S t r i n g ();
r e t u r n s . str ();
} };
. . . .
Classe ListeDeCourses
I 2. Écrivez en C++ la classeListeDeCoursesdonnée par le diagramme de classes précédent. La méthodeprixTotalrenvoie la somme des prix de tous les produits de la liste de courses. Vous ajouterez la surcharge de l’opérateur<< pour écrire une liste de courses dans unstd::ostream.
c l a s s L i s t e D e C o u r s e s { p r i v a t e:
std :: vector < P r o d u i t * > l i s t e C o u r s e s ; p u b l i c:
// le destucteur
~ L i s t e D e C o u r s e s () {
f o r ( P r o d u i t * p : t h i s- > l i s t e C o u r s e s ) d e l e t e p ;
}
v o i d a j o u t e r ( P r o d u i t * p ) { l i s t e C o u r s e s . p u s h _ b a c k ( p );
}
d o u b l e p r i x T o t a l () c o n s t { d o u b l e t o t a l = 0;
f o r ( P r o d u i t * p : l i s t e C o u r s e s ) t o t a l += p - > g e t P r i x ();
//
r e t u r n t o t a l ; }
std :: s t r i n g t o S t r i n g () c o n s t { std :: o s t r i n g s t r e a m s ;
f o r ( P r o d u i t * p : t h i s- > l i s t e C o u r s e s ) { s < < p - > t o S t r i n g () < < " \ n ";
}
s < < " - - - -\ n ";
s < < " T o t a l : " < < t h i s- > p r i x T o t a l () < < " e u r o s \ n "; s < < " - - - -\ n ";
r e t u r n s . str ();
}
f r i e n d std :: o s t r e a m &o p e r a t o r< <( std :: o s t r e a m & f , c o n s t L i s t e D e C o u r s e s & l ) {
r e t u r n f < < l . t o S t r i n g ();
} };
. . . . On veut ajouter à la classeListeDeCoursesla méthodeenregistrerqui écrit la liste de courses courante dans un fichier (typeofstream. Le nom du fichier (de typestd::string) est passé en paramètre. Si une erreur se produit à l’ouverture du fichier, l’exception FileExceptionavec un message d’erreur est émise.
I 3. Écrivez en C++ la classe FileExceptiondans la laquelle vous redéfinirez la méthodewhat().
#i n c l u d e < e x c e p t i o n >
c l a s s F i l e E x c e p t i o n : p u b l i c std :: e x c e p t i o n { p r i v a t e:
std :: s t r i n g msg ; p u b l i c:
F i l e E x c e p t i o n ( std :: s t r i n g s ) : msg ( s ) {};
v i r t u a l c o n s t c h a r * w h a t () c o n s t n o e x c e p t o v e r r i d e { r e t u r n msg . c _ s t r ();
} };
. . . . I 4. Écrivez en C++ la méthodeenregisterqui écrit lesProduitd’uneListeDeCourses
courante dans un fichier. Si vous avez besoin de (re)définir d’autres méthodes, vous les écrirez en précisant bien les classes auxquelles elles appartiennent.
v o i d L i s t e D e C o u r s e s :: e n r e g i s t r e r (c o n s t std :: s t r i n g & f i l e n a m e ) c o n s t { std :: o f s t r e a m oos ( f i l e n a m e );
i f (! oos . i s _ o p e n ())
throw F i l e E x c e p t i o n (" E r r e u r : " + f i l e n a m e + " o u v e r t u r e i m p o s s i b l e ");
// ok écrire la liste
f o r ( P r o d u i t * p : t h i s- > l i s t e C o u r s e s ) oos < < * p ;
oos . c l o s e ();
}
avec dans la classeProduit
v i r t u a l v o i d e c r i r e P r o d u i t ( std :: o f s t r e a m & f ) c o n s t =0;
f r i e n d std :: o f s t r e a m & o p e r a t o r< <( std :: o f s t r e a m & f , c o n s t P r o d u i t & p ) { p . e c r i r e P r o d u i t ( f );
r e t u r n f ; }
dans la classeLeggoo
v i r t u a l v o i d e c r i r e P r o d u i t ( std :: o f s t r e a m & f ) c o n s t o v e r r i d e { f . w r i t e ((c h a r *) t h i s, s i z e o f( L e g g o o ));
}
et enfin, dans la classe Pull
v i r t u a l v o i d e c r i r e P r o d u i t ( std :: o f s t r e a m & f ) c o n s t o v e r r i d e { f . w r i t e ((c h a r *) t h i s, s i z e o f( P u l l ));
}
. . . .
Classe de test
I 5. Écrivez en C++ la fonction maindans laquelle :
— vous créerez 2 listes de courses, une pour Mario et l’autre pour la Prin- cesse Pêche avec les produits suivants :
Liste de Mario Liste de Princesse Pêche
Leggoo - Planet destroyer - 90 euros - âge 12 ans Pull - 40 euros - magenta Leggoo - Ma Petite Ferme - 70 euros - âge 6 an Pull - 55 euros - rainbow
Pull - 40 euros - rouge Leggo - Ma Happy Fish Tank - 10 euros Vous appliquerez une réduction de 50% sur le premier Leggoo de Mario,
et une réduction de 30% sur son second Leggo. Pour Princesse Pêche, vous appliquerez une réduction de 50% sur deuxième Pull.
— Vous afficherez les deux listes de courses avec, pour chacune, leur prix total.
— Vous enregistrez la liste de courses de Mario dans un fichier de nom
"Mario". Vous ferez l’enregistrement dans un try-catch et, en cas d’er-
reur, vous afficherez sur la sortie d’erreur standard le message fourni par l’exception.
L’exécution de votre programme doit donner :
MarioListe :
Leggoo - pour âges 12+ - soldé à 45 euros Leggoo - pour âges 6+ - soldé à 49 euros Pull - rouge - 40 euros
---
Total : 134 euros
--- PêcheListe :
Pull - magenta - 40 euros
Pull - rainbow - soldé à 27.5 euros Leggoo - pour âges 8+ - 10 euros --- Total : 77.5 euros
---
Par exemple, l’ouverture erronée du fichier/usr/Marioproduira :
Erreur : /usr/Mario ouverture impossible
i n t m a i n () {
L i s t e D e C o u r s e s M a r i o L i s t e , P e c h e L i s t e ; //
P r o d u i t * p = new L e g g o o (90.0 , 1 2 ) ; p - > s e t T a u x ( 0 . 5 ) ;
M a r i o L i s t e . a j o u t e r ( p );
p = new L e g g o o ( 7 0 . 0 ) ; p - > s e t T a u x ( 0 . 7 ) ; M a r i o L i s t e . a j o u t e r ( p );
M a r i o L i s t e . a j o u t e r (new P u l l (40.0 , " r o u g e "));
//
P e c h e L i s t e . a j o u t e r (new P u l l (40 , " m a g e n t a "));
p = new P u l l (55 , " r a i n b o w ");
p - > s e t T a u x ( 0 . 5 ) ; P e c h e L i s t e . a j o u t e r ( p );
P e c h e L i s t e . a j o u t e r (new L e g g o o (10 , 8 ) ) ; //
std :: c o u t < < " M a r i o L i s t e : " < < std :: e n d l < < M a r i o L i s t e ; std :: c o u t < < " P ê c h e L i s t e : " < < std :: e n d l < < P e c h e L i s t e ; //
t r y {
M a r i o L i s t e . e n r e g i s t r e r (" / usr / M a r i o ");
}
c a t c h (c o n s t F i l e E x c e p t i o n & e ) { std :: c e r r < < e . w h a t () < < std :: e n d l ; }
r e t u r n E X I T _ S U C C E S S ; }
. . . .