Quelques exercices pour apprivoiser quelques éléments du langage C++ apparaissant au chapitre 4 des notes de cours.
Soit la classe dessinable suivante, que vous n'avez pas le droit de modifier :
#include <ostream>
struct dessinable {
virtual void dessiner(std::ostream &) const = 0;
virtual ~dessinable() = default;
};
// ...
... de même que le code client suivant, que vous n'avez pas non plus le droit de modifier :
// ...
#include <iostream>
#include <algorithm>
#include <iterator>
bool comparer_indirect(const forme *f0, const forme *f1) {
return *f0 < *f1;
}
int main() {
carre c{ 3, '#' };
rectangle r{ 4, 12, 'W' };
triangle t{ 5, 'A' };
forme * formes[] { &c, &r, &t };
std::sort(std::begin(formes), std::end(formes), comparer_indirect);
for(forme * p : formes)
dessiner(std::cout, *p);
}
Complétez ce programme (le code manquant va entre la classe dessinable et le code client; ça tombe bien!) de manière à ce que le code compile, s'exécute correctement et affiche ce qui suit. Des explications et des commentaires suivent juste après :
###
###
###
A
AAA
AAAAA
AAAAAAA
AAAAAAAAA
WWWWWWWWWWWW
WWWWWWWWWWWW
WWWWWWWWWWWW
WWWWWWWWWWWW
Ce que vous devez savoir :
struct base { virtual int f() const { return 3; } };
struct derive : base { int f() const override { return 4; } };
struct b0 { int n; b(int n) : n{ n } {} };
struct b1 { int m; b(int m) : m{ m } {} };
struct d : b0, b1 { d(int m, int n) : b0{ n }, b1{ m } { } };
Il y a quelques exercices pour vous au bas de http://h-deb.ca/Sujets/AuSecours/Bref-pointeurs.html ce qui peut vous divertir!
Examinez le programme suivant (voir https://wandbox.org/permlink/R2CmReCE9ji2tOj6 pour une version en-ligne) :
#include <ostream>
#include <string>
class personne {
std::string nom_;
public:
personne(const std::string &nom) : nom_{ nom } {
}
std::string nom() const {
return nom_;
}
virtual std::ostream& presenter(std::ostream &os) const {
return os << "Je me presente : " << nom_;
}
};
struct etudiant : personne {
etudiant(const std::string &nom) : personne { nom } {
}
std::ostream& presenter(std::ostream &os) const override {
return os << "Ouais, mon nom est " << nom() << " et j'etudie fort!";
}
};
////////
#include <iostream>
void presenter_v0(const etudiant &e) {
e.presenter(std::cout) << '\n';
}
void presenter_v1(const personne &p) {
p.presenter(std::cout) << '\n';
}
void presenter_v2(etudiant e) {
e.presenter(std::cout) << '\n';
}
void presenter_v3(personne p) {
p.presenter(std::cout) << '\n';
}
void presenter_v4(etudiant &e) {
e.presenter(std::cout) << '\n';
}
void presenter_v5(personne &p) {
p.presenter(std::cout) << '\n';
}
int main() {
const etudiant e{ "Carol" };
presenter_v0(e);
presenter_v1(e);
presenter_v2(e);
presenter_v3(e);
// presenter_v4(e);
// presenter_v5(e);
}
Expliquez les raisons pour lesquelles les affichages réalisés par presenter_v0(), presenter_v1(), presenter_v2() et presenter_v3() sont tels qu'ils sont.
Les appels à presenter_v4() et presenter_v5() sont en commentaires car ils ne compileraient pas. Pourquoi donc?
Soit le programme suivant :
#include <cstdio>
// version simplifiée d'un truc plus intéressant;
// nous y reviendrons peut-être
struct Noisy {
Noisy() { // ctor par défaut
std::puts("Noisy::Noisy()");
}
Noisy(const Noisy&) { // ctor de copie
std::puts("Noisy::Noisy(const Noisy&)");
}
Noisy& operator=(const Noisy&) { // affectation de copie
std::puts("Noisy::operator=(const Noisy&)");
return *this;
}
~Noisy() { // dtor
std::puts("Noisy::~Noisy()");
}
};
Noisy f(Noisy n) {
Noisy m;
m = n;
return m;
}
int main() {
Noisy n;
n = f(n);
}
Sachant que std::puts() affiche simplement une chaîne à la console (suivie d'un saut de ligne), qu'affichera ce programme? Solution sur https://wandbox.org/permlink/HPllrN9gKkRaM9GA mais faites l'effort avant de regarder!
Soit le programme suivant :
#include <iostream>
using namespace std;
const int a = 3,
b = 4;
/////// VOTRE CODE VA ICI (DÉBUT)
// ...
// ...
// ...
/////// VOTRE CODE VA ICI (FIN)
int main() {
const int *p = choisir();
cout << '\n' << *p << endl;
}
Écrivez la fonction choisir() qui demande à l'usager s'il souhaite la constante a ou la constante b, et qui retourne l'adresse de cette variable pour que le programme principal affiche la valeur de celle qui aura été choisie (solution sur https://wandbox.org/permlink/7PQw93ajcgXPBP2n quand vous serez prêt(e)s).
Soit le programme (incomplet) suivant :
#include <iostream>
#include <cmath>
using namespace std;
/////// VOTRE CODE VA ICI (DÉBUT)
// ...
// ...
// ...
/////// VOTRE CODE VA ICI (FIN)
template <class T>
enrobage<T> enrober(const T &obj, char pre, char post) {
return { obj, pre, post };
}
int main() {
point2d<int> pi0, pi1{ 1, 1 };
cout << "Distance entre " << pi0 << " et " << pi1 << " == "
<< distance(pi0, pi1) << endl;
cout << "Distance entre " << enrober(pi0, '(', ')') << " et " << enrober(pi1, '(', ')') << " == "
<< distance(pi0, pi1) << endl;
point2d<double> pd0{ 1.5, 2.5 }, pd1{ 0.5, -0.5 };
cout << "Distance entre " << pd0 << " et " << pd1 << " == "
<< distance(pd0, pd1) << endl;
cout << "Distance entre " << enrober(pd0, '(', ')') << " et " << enrober(pd1, '(', ')') << " == "
<< distance(pd0, pd1) << endl;
}
Sachant que la bibliothèque <cmath> expose entre autres les fonctions std::sqrt(x) qui retourne la racine carrée de x, et std::pow(base,exposant) qui retourne la valeur de base une fois celle-ci élevée à la puissance exposant, votre mission est :
L'affichage attendu pour le programme sera :
Distance entre 0 0 et 1 1 == 1.41421
Distance entre (0 0) et (1 1) == 1.41421
Distance entre 1.5 2.5 et 0.5 -0.5 == 3.16228
Distance entre (1.5 2.5) et (0.5 -0.5) == 3.16228
Pour un solutionnaire, voir https://wandbox.org/permlink/8WODjqsxfXVklwAt