Outils d'utilisateurs

Outils du Site


ce_que_vous_pouvez_encore_apprendre
Ce cours est une mise à jour du cours C++ de OpenClassRoom pour le mettre à jour pour le C++11/14. Le cours d'origine est consultable sur la page suivante : Programmez avec le langage C++, par Mathieu Nebra et Matthieu Schaller. Ce cours est sous licence CC-BY-NC-SA.

Retourner au sommaire principal

Ce que vous pouvez encore apprendre

Qu'on se le dise : bien que cet ouvrage sur le C++ s'arrête là, vous ne savez pas tout sur tout. D'ailleurs, personne ne peut vraiment prétendre tout savoir sur le C++ et toutes ses bibliothèques.

En fait, l'objectif n'est pas de tout savoir mais d'être capables d'apprendre ce dont vous avez besoin lorsque c'est nécessaire.

Si je devais moi-même vous apprendre tout sur le C++, j'y passerais toute une vie (et encore, cela serait toujours incomplet). Du coup, plutôt que de tout vous apprendre, j'ai choisi de vous enseigner de bonnes bases tout au long du cours. Ce chapitre a pour but, maintenant que le cours est fini, de vous donner un certain nombre de pistes pour continuer votre apprentissage.

Ce chapitre est seulement là pour vous présenter de nouvelles notions, pas pour vous les expliquer. Ne soyez donc pas surpris si je suis beaucoup plus succinct que d'habitude. Imaginez ce chapitre comme un sommaire de ce qu'il vous reste à apprendre.

Plus loin avec le langage C++

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 ayez besoin un jour, je vais vous présenter rapidement ces notions. À vous ensuite d'approfondir vos connaissances, par exemple en lisant des cours écrits par d'autres membres du Site du Zéro sur le C++, en lisant des livres dédiés au C++, ou tout simplement en faisant une recherche Google.

Liste des cours de C++ sur le Site du Zéro

Voici les notions que je vais vous présenter ici :

  • l'héritage multiple ;
  • les espaces de noms ;
  • les types énumérés ;
  • les typedef.

L'héritage multiple

L'héritage multiple consiste à hériter de plusieurs classes à la fois (figure suivante). Nous avons déjà fait cela dans la partie sur Qt, pour pouvoir utiliser une interface dessinée dans Qt Designer.

Héritage multiple

Pour hériter de plusieurs classes, il suffit de mettre une virgule entre les noms de classe, comme on l'avait fait :

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. Pourquoi ? 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 un coup d'œil à cette notion mais juste un coup d'œil de préférence, car vous ne devriez pas y avoir recours très souvent.

Les namespaces

Souvenez-vous : dès le début du tutoriel C++, je vous ai fait utiliser les objets cout et cin qui permettent d'afficher un message dans la console et de récupérer le texte saisi au clavier.

Voici le tout premier code source C++ que vous aviez découvert mais avec le vrai nom des objets :

#include <iostream>
 
int main()
{
        std::cout << "Hello world!" << std::endl;
        return 0;
}

Le préfixe std:: correspond à ce qu'on appelle un namespace, c'est-à-dire en français un espace de noms. Les namespaces sont utiles dans de très gros programmes où il y a beaucoup de noms différents de classes et de variables.

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 (figure suivante).

Namespaces

Si la classe est dans un namespace, on doit préfixer son intitulé par le nom du namespace :

Jeu3D::Couleur rouge; // Utilisation de la classe Couleur 
                      // située dans le namespace Jeu3D
Fenetre::Couleur vert; // Utilisation d'une AUTRE classe appelée elle 
                       // aussi Couleur, dans le namespace Fenetre

Les espaces de noms sont vraiment comme des noms de famille pour les noms de variables.

Le namespace « std » est utilisé par toute la bibliothèque standard du C++. Il faut donc mettre ce préfixe devant chaque nom issu de la bibliothèque standard (cout, cin, vector, string. ..). Il est aussi possible, comme on le fait depuis le début, 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.

Certains programmeurs préfèrent éviter d'utiliser « using namespace » car, en lisant le code ensuite, on ne sait plus vraiment à quel namespace le nom se rapporte.

Les types énumérés

Dans un programmes, on a parfois besoin de manipuler des variables qui ne peuvent prendre qu'un petit nombre de valeurs différentes. Tenez, 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;
}

Les typedefs

Vous en voulez encore ? Voyons donc une petite astuce bien pratique pour économiser du texte. 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 !

Les typedefs (redéfinition de type en français) permettent de créer des alias sur des noms de types pour éviter de devoir en taper l'intitulé à rallonge. 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.

Plus loin avec d'autres bibliothèques

Vous en avez fait l'expérience dans ce cours avec Qt, 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

Si vous avez lu le cours sur le langage C (Apprenez à programmer en C dans la même collection), vous avez certainement appris à utiliser la bibliothèque SDL pour créer des jeux en 2D, comme par exemple le « Mario Sokoban ».

On peut tout à fait utiliser la SDL en C++ mais il existe d'autres bibliothèques utilisant la force de la programmation orientée objet, qui sont plus adaptées à notre langage favori.

Allegro est une bibliothèque multiplateforme dédiée aux jeux vidéo. Ses créateurs ont particulièrement optimisé leurs fonctions de sorte 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 et son créateur, Laurent Gomila, passe souvent sur les forums du Site du Zéro pour aider les débutants. C'est donc un bon choix pour se lancer dans le domaine passionnant des jeux vidéo.

Faire de la 3D

Encore un domaine très vaste et très intéressant. De nos jours, la plupart des jeux vidéo sont réalisés en 3D et beaucoup de monde se lance dans la programmation C++ justement dans le but de réaliser des jeux en trois dimensions. De base, il existe deux APIs (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 APIs 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 de plus haut niveau et donc 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, je vous en cite deux qui sont bien connus et simples d'utilisation : Irrlicht et Ogre3D.

Ces deux bibliothèques proposent globalement le même lot de classes et de fonctions. Comme bien souvent, les documentations de ces moteurs sont en anglais mais, vous avez de la chance, il existe sur le Site du Zéro deux cours d'introduction à ces outils.

Cours sur les moteurs 3D

uploads.siteduzero.com_files_401001_402000_401052.jpg Aperçu d'un jeu réalisé avec Irrlicht

Pour choisir entre ces deux bibliothèques (ou parmi d'autres encore), je vous conseille de regarder quelques codes sources d'exemple et le début des cours d'introduction. Vous serez alors plus à même de décider laquelle vous plaît le plus.

Plus de GUI

Vous avez appris à utiliser Qt dans ce cours mais, bien entendu, il n'y a pas que ce framework pour réaliser des applications avec des fenêtres. En fait, le choix est gigantesque ! Je vais ici vous présenter brièvement deux bibliothèques que l'on voit dans de nombreux projets.

wxWidgets

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. Vous devriez donc facilement vous y retrouver. L'éditeur Code::Blocks que nous utilisons depuis le début du cours est, par exemple, basé sur wxWidgets. On peut donc réaliser de belles choses.

.NET

.NET (prononcez « dot net ») est le framework de création de fenêtres développé par Microsoft. En plus des fonctionnalités liées aux GUIs, .NET permet d'interagir complètement 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

Alors là, c'est plus simple de faire son choix. Il y a bien sûr 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 : du wav au mp3, tout y est. On peut ensuite jouer ces sons, les transformer, les filtrer, les distordre, y ajouter des effets, etc. Il n'y a presque aucune limite. Je crois que vous l'avez compris, c'est le choix à faire dans le domaine.

boost

Je ne pouvais pas terminer ce chapitre sans vous parler de boost. C'est la bibliothèque incontournable de ces dernières années. Elle propose près d'une centaine de modules dédiés à des tâches bien spécifiques. On peut vraiment la voir comme une extension de la SL. Chaque module de boost a été écrit avec grand soin souvent dans le cadre de la recherche en informatique. C'est donc un vrai gage de fiabilité et d'optimisation. Je ne peux pas vous présenter ici tout ce qu'on y trouve. Il me faudrait pour cela un deuxième livre au moins aussi long que celui-ci. Mais je vous invite à jeter un œil à la liste complète des fonctionnalités, sur son site web. En résumé, on y trouve :

  • de nombreux outils mathématiques (générateurs aléatoires, fonctions compliquées, matrices, nombres hyper-complexes, outils pour les statistiques, …) ;
  • des pointeurs intelligents : ce sont des outils qui gèrent intelligemment la mémoire et évitent les problèmes qui surviennent quand on manipule dangereusement des pointeurs ;
  • des outils dédiés à la communication sur le réseau ;
  • des fonctions pour la mesure du temps et de la date ;
  • des outils pour naviguer dans l'arborescence des fichiers ;
  • des outils pour la manipulation d'images de tout format ;
  • des outils pour utiliser dans un programme plusieurs cœurs d'un processeur ;
  • des outils pour exécuter un code source Python en C++ ;

Vous voyez, il y a vraiment de tout. 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. C'est vraiment du grand art ! Je ne peux que vous recommander d'user et même d'abuser de boost.

Vous n'êtes pas seuls !

Comme je vous l'ai dit, cette liste n'est bien sûr pas complète. 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. Vous pouvez aussi poser des questions sur le forum C++ du Site du Zéro. La communauté se fera un plaisir de vous répondre et de vous guider dans vos choix !

Forum C++ du Site du Zéro

Bonne continuation ! :-)

Le cours de C++ 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.

N'hésitez pas à lire le dernier chapitre “Ce que vous pouvez encore apprendre”, qui vous donne de nombreuses ouvertures pour continuer votre apprentissage si vous le désirez. :)

Retourner au sommaire principal

ce_que_vous_pouvez_encore_apprendre.txt · Dernière modification: 2014/04/07 12:20 par gbdivers