Le langage C++ est suffisamment riche pour qu'il vous reste encore de nombreuses notions à découvrir. Certaines d'entre elles sont particulièrement complexes, je ne vous le cache pas, et vous n'en aurez pas besoin tout le temps.
Toutefois, au cas où vous en auriez besoin un jour, je vais vous présenter rapidement ces notions :
l'héritage multiple ;
les espaces de noms ;
les types énumérés ;
les
typedef
.
Découvrez l'héritage multiple
Pour hériter de plusieurs classes, il suffit de mettre une virgule entre les noms de classe :
class FenCalculatrice : public QWidget, public Ui::FenCalculatrice
{
};
C'est une notion qui paraît simple mais qui, en réalité, est très complexe.
En fait, la plupart des langages de programmation plus récents, comme Java et Ruby, ont carrément décidé de ne pas gérer l'héritage multiple parce que cela peut être utile dans certaines conditions assez rares mais, si on l'utilise mal (quand on débute) cela peut devenir un cauchemar à gérer. Bref, jetez seulement un coup d'œil à cette notion car vous ne devriez pas y avoir recours très souvent.
Découvrez les namespaces
Souvenez-vous : les objets cout
et cin
permettent d'afficher un message dans la console, et de récupérer le texte saisi au clavier.
#include <iostream>
int main()
{
std::cout << "Hello world!" << std::endl;
return 0;
}
Quand vous avez beaucoup de noms différents dans un programme, il y a un risque que deux classes aient le même nom. Par exemple, vous pourriez utiliser deux classes Couleur
dans votre programme : une dans votre bibliothèque "Jeu3D" et une autre dans votre bibliothèque "Fenetre".
Normalement, avoir 2 classes du même nom est interdit… sauf si ces classes sont chacune dans un namespace différent ! Imaginez que les namespaces sont comme des boîtes qui évitent de mélanger les noms de classes et de variables :
Si la classe est dans un namespace, on doit préfixer son intitulé par le nom du namespace :
Jeu3D::Couleur violet; // Utilisation de la classe Couleur située dans le namespace Jeu3D
Fenetre::Couleur rose; // Utilisation d'une AUTRE classe appelée elle aussi Couleur, dans le namespace Fenetre
Il est aussi possible d'utiliser la directive using namespace
au début du fichier :
using namespace std;
Grâce à cela, dans tout le fichier, le compilateur saura que vous faites référence à des noms définis dans l'espace de noms std
. Cela vous évite d'avoir à répéter std::
partout.
Découvrez les types énumérés
Dans un programme, on a parfois besoin de manipuler des variables qui ne peuvent prendre qu'un petit nombre de valeurs différentes.
Si vous devez décrire les trois niveaux de difficulté de votre jeu, vous pourriez utiliser un int
valant 1, 2 ou 3. Mais ce n'est pas très sécurisé, on n'est pas sûr que l'entier prendra toujours une de ces trois valeurs. Il serait bien d'avoir un type qui ne peut prendre que ces trois valeurs.
Un type énuméré se déclare comme ceci :
enum Niveau{Facile, Moyen, Difficile};
On l'utilise alors comme n'importe quelle autre variable :
int main()
{
Niveau level;
//…
if(level == Moyen)
cout << "Vous avez choisi le niveau moyen" << endl;
//…
return 0;
}
C'est bien pratique. En plus, cela rend le code plus lisible : la ligne if(level == Moyen)
est plus claire à lire que if(level == 2)
, on n'a pas besoin de réfléchir à ce que représente ce 2.
On retrouve souvent les types énumérés dans des codes employant les tests switch
.
Voici un exemple utilisant un type énuméré pour les directions d'un personnage sur une carte :
enum Direction{Nord, Sud, Est, Ouest};
int main()
{
Direction dir;
Personnage p;
//…
switch(dir)
{
case Nord: p.avancerNord(); break;
case Sud: p.avancerSud(); break;
case Est: p.avancerEst(); break;
case Ouest: p.avancerOuest(); break;
}
//…
return 0;
}
Vous en voulez encore ? Voyons donc une petite astuce bien pratique pour économiser du texte.
Découvrez les typedef
Certains types sont vraiment longs à écrire. Prenez par exemple un itérateur sur une table associative de chaînes de caractères et de vector
d'entiers. Un objet de ce type se déclare comme ceci :
std::map<std::string, std::vector<int> >::iterator it;
C'est un peu long !
Par exemple, si l'on souhaite renommer le type précédent en Iterateur
, on écrit :
typedef std::map<std::string, std::vector<int> >::iterator Iterateur
À partir de là, on peut déclarer des objets de ce type en utilisant l'alias :
Iterateur it;
Évidemment, si on n'utilise qu'une seule fois un objet de ce type, on ne gagne rien ; mais dans de longs codes, cela peut devenir pratique.
Utilisez d'autres bibliothèques pour…
On utilise souvent des bibliothèques externes en C++. Le problème, c'est qu'il y en a des milliers, et que l'on ne sait pas forcément laquelle choisir. Tenez, rien que pour créer des fenêtres, je pourrais vous citer une dizaine de bibliothèques performantes. Heureusement, je suis là pour vous aider un peu dans cette jungle.
… créer des jeux en 2D
Allegro est une bibliothèque multiplateforme dédiée aux jeux vidéo. Ses créateurs ont particulièrement optimisé leurs fonctions, afin que les jeux réalisés soient aussi rapides que possible. Elle gère tout ce qui est nécessaire à la création d'un jeu, les joysticks, le son, les images, les boutons et autres cases à cocher. Son principal défaut, pour nous francophones, est que sa documentation est en anglais.
La SFML (Simple and Fast Multimedia Library) se décrit elle-même comme étant une alternative orientée objet à la SDL. Cette bibliothèque est très simple d'utilisation, et propose également tous les outils nécessaires à la création de jeux, sous forme de classes. Un autre avantage est qu'elle est découpée en petits modules indépendants, ce qui permet de se restreindre à la partie dédiée au son ou à la partie dédiée à la communication sur le réseau, par exemple. Enfin, tout est documenté en français.
… faire de la 3D
Beaucoup de monde se lance dans la programmation C++ justement dans le but de réaliser des jeux en 3D. De base, il existe deux API (Application Programming Interface : interface de programmation) pour manipuler les cartes graphiques : DirectX et OpenGL, la première n'étant disponible que sous Windows. Vous avez certainement déjà dû entendre ces deux noms.
Avec cela, on peut tout faire, tout dessiner, tout réaliser. Le problème, c'est que ces deux API ne proposent que des fonctionnalités de base, comme dessiner un triangle ou un point.
Réaliser une scène complète avec un personnage qui bouge et des animations demande donc beaucoup de travail. C'est pour cela qu'il existe ce qu'on appelle des moteurs 3D, qui proposent des fonctionnalités plus simples à utiliser. Tous les jeux vidéo que vous connaissez utilisent des moteurs 3D, c'est la vraie boîte à outils qu'utilisent les programmeurs.
Parmi tous les moteurs existants, en voici deux connus et simples d'utilisation : Irrlicht et Ogre3D.
… créer des programmes en fenêtre
wxWidgets ressemble beaucoup à Qt dans sa manière de créer les fenêtres et les widgets qui s'y trouvent. On y retrouve aussi la notion de signaux, de slots et de connexions entre eux.
.NET est le framework de création de fenêtres développé par Microsoft. En plus des fonctionnalités liées aux interfaces utilisateurs, il permet d'interagir avec Windows, et d'accéder à de nombreux services comme la communication sur le réseau ou la gestion du son. Bref, c'est une bibliothèque vraiment très complète. Presque tous les logiciels que vous connaissez sous Windows l'utilisent aujourd'hui. C'est vraiment un outil incontournable. De plus, elle est très bien documentée, ce qui permet de trouver rapidement et facilement les informations nécessaires. Son seul défaut est qu'elle n'est disponible entièrement que sous Windows. Il existe des projets comme Mono qui tentent d'en proposer une version sous Mac et Linux, mais tout n'est pas encore disponible.
… manipuler du son
Il y a beaucoup de bibliothèques qui permettent de manipuler du son, mais il y en a une qui écrase tellement la concurrence que je vais m'y limiter. Il s'agit de FMOD EX. Presque tous les jeux vidéo que vous connaissez l'utilisent, c'est dire !
Cette bibliothèque permet de lire à peu près tous les formats de fichiers sonores (.wav ; .mp3…). On peut ensuite jouer ces sons, les transformer, les filtrer, les distordre, y ajouter des effets, etc.
Il n'y a presque aucune limite.
… compléter la bibliothèque standard !
Je ne pouvais pas terminer ce chapitre sans vous parler de boost.
En résumé, on y trouve des outils pour :
faire des mathématiques (générateurs aléatoires, fonctions compliquées, matrices, nombres hypercomplexes, outils pour les statistiques…) ;
gérer intelligemment la mémoire et éviter les problèmes qui surviennent quand on manipule dangereusement des pointeurs ;
faire de la communication sur le réseau ;
mesurer du temps et de la date ;
naviguer dans l'arborescence des fichiers ;
manipuler des images de tout format ;
utiliser dans un programme plusieurs cœurs d'un processeur ;
exécuter un code source Python en C++.
La plupart des fonctionnalités sont proposées sous forme de templates, et donc entièrement optimisées pour votre utilisation lors de la compilation. Je ne peux que vous recommander d'user et même d'abuser de boost
.
Et voilà !
L'important est de choisir un outil avec lequel vous vous sentez à l'aise. N'hésitez pas à surfer sur le Web pour trouver d'autres options, ou d'autres utilisateurs qui présentent leurs préférences.
Consultez les annexes
Je vous ai réuni quelques informations utiles pour vous aider à comprendre des codes sources que vous aurez trouvés au hasard du Web, et qui contiendraient des éléments du C++ que nous n'avons pas abordés dans le cours.
Le cours s'arrête là.
J'espère que vous aurez appris au moins autant de choses que vous ne l'espériez, et surtout que vous avez formé votre esprit à être capable de programmer en toutes circonstances par la suite.
Je vous souhaite une très belle continuation !