MOOC Intro. POO C++ Corrigés semaine 1 Les corrigés proposés correspondent à l'
MOOC Intro. POO C++ Corrigés semaine 1 Les corrigés proposés correspondent à l'ordre des apprentissages : chaque corrigé correspond à la solution à laquelle vous pourriez aboutir au moyen des connaissances acquises jusqu'à la semaine correspondante. Exercice 1 : la classe Cercle Cet exercice correspond à l'exercice n°46 (pages 109 et 291) de l'ouvrage C++ par la pratique (3e édition, PPUR). Cet exercice se fait de façon assez similaire au tutoriel sur les rectangles. Comment commencer ? À ce niveau, il suffit de suivre l'enoncé : « définissez une classe Cercle » : class Cercle { }; « ayant comme attributs privés » class Cercle { private: }; « le rayon du cercle (de type double), et les coordonnées de son centre. » class Cercle { private: double rayon; double x; // abscisse du centre double y; // ordonnée du centre }; Remarque : les meilleurs analystes peuvent faire remaquer que le centre est un «point» et écrire, de façon encore plus propre, le code suivant : struct Point { double x; // abscisse double y; // ordonnée }; class Cercle { private: double rayon; Point centre; }; Remarque 2 : les meilleurs analystes et programmeurs « objet » en feront bien sûr une classe plutôt qu'une struct... ...avec une encapsulation correcte (voir l'exercice 3). On continue ensuite à suivre l'énoncé à la lettre : Déclarez ensuite les méthodes «get» et «set» correspondantes : class Cercle { void getCentre(double& x_out, double& y_out) const { x_out = x; y_out = y; } void setCentre(double x_in, double y_in) { x = x_in; y = y_in; } double getRayon() const { return rayon; } void setRayon(double r) { if (r < 0.0) r = 0.0; rayon = r; } private: double rayon; double x; // abscisse du centre double y; // ordonnée du centre }; Attention à bien faire la différence entre x en tant qu'argument de la méthode et x en tant qu'attribut de l'instance. Dans les cas ambigus comme ci-dessus, il faut lever l'ambiguité en utilisant le pointeur this (pour indiquer l'attribut), ou alors changer de noms. Ah! QUESTION : ces méthodes sont-elles privées ou publiques ? Publiques évidemment car on doit pouvoir les utiliser hors de la classe (elles font partie de l'interface). class Cercle { public: void getCentre(double &x, double &y) const { ... // comme avant }; Remarque 3 : les meilleurs analystes continueraient ici sur leur lancée et choisiraient les prototypes suivants pour getCentre et setCentre : Point getCentre() const { return centre; } void setCentre(const Point& p) { centre = p; } On termine ensuite notre classe de façon très similaire à ce qui précède : #include <cmath> // pour M_PI class Cercle { public: double surface() const { return M_PI * rayon * rayon; } bool estInterieur(double x1, double y1) const { return (((x1-x) * (x1-x) + (y1-y) * (y1-y)) <= rayon * rayon); } void getCentre(double& x, double& y) const { ... // suite comme avant Il ne reste plus qu'à tester : #include <iostream> // pour cout et endl #include <cmath> // pour M_PI et sqrt() using namespace std; // ... la classe Cercle comme avant int main () { Cercle c1, c2; c1.setCentre(1.0, 2.0); c1.setRayon(sqrt(5.0)); // passe par (0, 0) c2.setCentre(-2.0, 1.0); c2.setRayon(2.25); // 2.25 > sqrt(5) => inclus le point (0, 0) cout << "Surface de C1 : " << c1.surface() << endl; cout << "Surface de C2 : " << c2.surface() << endl; cout << "position du point (0, 0) : "; if (c1.estInterieur(0.0, 0.0)) cout << "dans"; else cout << "hors de"; cout << " C1 et "; if (c2.estInterieur(0.0, 0.0)) cout << "dans"; else cout << "hors de"; cout << " C2." << endl; return 0; } On pourrait même faire une fonction pour tester les points : void testPoint(double x, double y, Cercle c1, Cercle c2) { cout << "position du point (" << x << ", " << y << ") : "; if (c1.estInterieur(x, y)) cout << "dans"; else cout << "hors de"; cout << " C1 et "; if (c2.estInterieur(x, y)) cout << "dans"; else cout << "hors de"; cout << " C2." << endl; } int main () { ... // comme avant testePoint(0.0, 0.0, c1, c2); testePoint(1.0, 1.0, c1, c2); testePoint(2.0, 2.0, c1, c2); return 0; } Solutions finales Version suffisante #include <iostream> #include <cmath> // pour M_PI et sqrt() using namespace std; class Cercle { public: double surface() const { return M_PI * rayon * rayon; } bool estInterieur(double x1, double y1) const { return (((x1-x) * (x1-x) + (y1-y) * (y1-y)) <= rayon * rayon); } void getCentre(double& x_out, double& y_out) const { x_out = x; y_out = y; } void setCentre(double x_in, double y_in) { x = x_in; y = y_in; } double getRayon() const { return rayon; } void setRayon(double r) { if (r < 0.0) r = 0.0; rayon = r; } private: double rayon; double x; // abscisse du centre double y; // ordonnée du centre }; int main () { Cercle c1, c2; c1.setCentre(1.0, 2.0); c1.setRayon(sqrt(5.0)); // passe par (0, 0) c2.setCentre(-2.0, 1.0); c2.setRayon(2.25); // 2.25 > sqrt(5) => inclus le point (0, 0) cout << "Surface de C1 : " << c1.surface() << endl; cout << "Surface de C2 : " << c2.surface() << endl; cout << "position du point (0, 0) : "; if (c1.estInterieur(0.0, 0.0)) cout << "dans"; else cout << "hors de"; cout << " C1 et "; if (c2.estInterieur(0.0, 0.0)) cout << "dans"; else cout << "hors de"; cout << " C2." << endl; return 0; } Version perfectionnée #include <iostream> // pour cout et endl #include <cmath> // pour M_PI et sqrt() using namespace std; // -----=====----- un point dans le plan -----=====----- struct Point { double x; // abscisse double y; // ordonnée }; // -----=====----- la classe Cercle -----=====----- class Cercle { // --- interface --- public: double surface() const { return M_PI * rayon * rayon; } bool estInterieur(const Point& p) const { return (((p.x-centre.x) * (p.x-centre.x) + (p.y-centre.y) * (p.y-centre.y)) <= rayon * rayon); } // interface des attributs Point getCentre() const { return centre; } void setCentre(const Point& p) { centre = p; } double getRayon() const { return rayon; } void setRayon(double r) { if (r < 0.0) r = 0.0; rayon = r; } // --- -------- --- private: double rayon; Point centre; }; // -------------------------------------------------------------------- void dans(bool oui) { if (oui) cout << "dans"; else cout << "hors de"; /* Note : peut aussi s'écrire : * * cout << (oui ? "dans" : "hors de"); */ } // -------------------------------------------------------------------- void test(Point p, Cercle c1, Cercle c2) { cout << "position du point (" << p.x << ", " << p.y << ") : "; dans(c1.estInterieur(p)); cout << " C1 et "; dans(c2.estInterieur(p)); cout << " C2." << endl; } // -------------------------------------------------------------------- int main () { Cercle c1, c2; Point p; p.x = 1.0; p.y = 2.0; c1.setCentre(p); c1.setRayon(sqrt(5.0)); // passe par (0, 0) p.x = -2.0; p.y = 1.0; c2.setCentre(p); c2.setRayon(2.25); // 2.25 > sqrt(5) => inclus le point (0, 0) cout << "Surface de C1 : " << c1.surface() << endl; cout << "Surface de C2 : " << c2.surface() << endl; p.x=0.0; p.y=0.0; test(p,c1,c2); p.x=1.0; p.y=1.0; test(p,c1,c2); return 0; } Exercice 2 : petit tour de magie Cet exercice correspond à l'exercice n°48 (pages 111 et 297) de l'ouvrage C++ par la pratique (3e édition, PPUR). Voici une solution possible (lisez les commentaires) : #include <iostream> using namespace std; // Un bout de papier... pour ce tour de magie class Papier { public: void ecrire(unsigned int un_age, unsigned int de_l_argent) { age = un_age; argent = de_l_argent; } unsigned int lire_age() const { return age ; } unsigned int lire_somme() const { return argent; } private: /* Ces 2 attributs spécifiquement, car d'une façon ou d'une autre * le spectateur rend intelligible l'information contenue sur le papier. */ unsigned int age; unsigned int argent; }; // -------------------------------------- class Assistant { public: void lire(const Papier& billet); void calculer(); unsigned int annoncer(); private: /* l'assistant mémorise dans son cerveau les valeurs lues * et le resultat du calcul. */ unsigned int age_lu; unsigned int argent_lu; unsigned int resultat; }; // -------------------------------------- class Spectateur { public: void arriver(); /* lorsqu'il entre dans la salle (avant * il n'"existe" pas pour nous) */ void ecrire(); // écrit sur le papier Papier montrer(); // montre le papier private: // ses spécificités unsigned int age; unsigned int argent; /* Dans cette version nous faisons l'hypothèse que * c'est le spectateur qui a un papier. * Dans d'autres modélisations, ce papier pourrait aussi bien * appartenir au magicien (variable locale à Magicien::tourDeMagie), * à l'assistant ou même "être dans la salle" (i.e. variable du main) */ Papier paquet_cigarettes; }; // -------------------------------------- class Magicien { public: void tourDeMagie(Assistant& asst, Spectateur& spect); /* Pour faire son tour, le magicien a besoin d'au moins * un spectateur et d'un assistant. */ private: /* partie privée ici car seul uploads/Marketing/ td1-corrige 17 .pdf
Documents similaires
-
13
-
0
-
0
Licence et utilisation
Gratuit pour un usage personnel Attribution requise- Détails
- Publié le Apv 28, 2021
- Catégorie Marketing
- Langue French
- Taille du fichier 0.1025MB