POO C++ - 1 - OpenClassrooms
POO C++ - 1 - OpenClassrooms
POO C++ - 1 - OpenClassrooms
Accueil
> Cours
> Programmez en orienté objet avec C++
> Découvrez la notion de POO
10 heures Difficile
L'idée de la programmation orientée objet, c'est de manipuler dans son code source des
éléments que l'on appelle des "objets". Dans un programme, cela peut être une fenêtre ou encore
un bouton, et il s'agit d'un mélange de plusieurs variables et fonctions.
Nous n'allons pas voir tout de suite comment faire pour créer des objets, en revanche nous allons
apprendre à en utiliser un.
Dans ce chapitre, nous allons nous pencher sur le cas de string .
J'ai déjà utilisé le type string , ce n'est pas une nouveauté pour moi ! C'est le type qui
permet de stocker du texte en mémoire, c'est cela ?
Je vais vous montrer comment fonctionne string "à l'intérieur du cube". Préparez-vous à d'horribles
vérités.
Mais alors, si l'ordinateur ne peut manipuler que des nombres, comment se fait-il qu'il puisse
afficher du texte à l'écran ?
64 @ 96 '
65 A 97 a
66 B 98 b
67 C 99 c
68 D 100 d
69 E 101 e
70 F 102 f
71 G 103 g
72 H 104 h
73 I 105 i
Nombre Lettre Nombre Lettre
74 J 106 j
75 K 107 k
76 L 108 l
77 M 109 m
C'est pour cela que les caractères accentués ne sont, de base, pas utilisables en C++ : ils
n'apparaissent pas dans la table ASCII.
Alors, à chaque fois que l'ordinateur voit le nombre , il prend cela pour la lettre A ?
Non, l'ordinateur ne traduit un nombre en lettre que si on le lui demande. En pratique, on se base sur le
type de la variable pour savoir si le nombre stocké est véritablement un nombre ou, en réalité, une lettre :
Si on utilise le type int pour stocker le nombre , l'ordinateur considérera que c'est un
nombre.
En revanche, si on utilise le type char pour stocker le nombre , l'ordinateur se dira "C'est la
lettre A".
Un char ne peut stocker qu'un seul caractère ? Comment fait-on alors pour stocker une
phrase entière ?
Eh bien, là non plus, ce n'est pas simple ! C'est un autre problème que nous allons voir...
Les tableaux permettant de retrouver côte à côte en mémoire plusieurs variables d'un même
type, ils sont le moyen idéal de stocker du texte.
Ainsi, il suffit de :
déclarer un tableau de char pour pouvoir stocker du texte (environ 100 caractères) :
cpp
1 char texte[100];
cpp
1 vector<char> texte;
Le texte n'est donc en fait qu'un assemblage de lettres, stocké en mémoire dans un tableau :
T e x t e
Chaque case correspond à un char . Tous ces char mis côte à côte forment du texte.
prévoir une taille suffisante pour stocker le texte que l'on souhaite sinon cela plante...
C'est là qu'intervient la programmation orientée objet : un développeur place le tout dans un cube facile
à utiliser où il suffit d'appuyer sur des boutons. Ce cube, c'est l'objet string .
cpp
1 #include <iostream>
2 #include <string> // Obligatoire pour pouvoir utiliser les objets string
7 int main()
8 {
10
11 return 0;
12 }
Pour pouvoir utiliser des objets de type string dans le code, il est nécessaire d'inclure l'en-tête de la
bibliothèque string . C'est ce que j'ai fait à la deuxième ligne.
Il y a plusieurs façons de créer un objet, celle que vous venez de voir est la plus simple. Et, oui, c'est
exactement comme si on avait créé une variable !
C'est bien tout le problème : variables et objets se ressemblent dans le code. Pour éviter la confusion, il
y a des conventions. La plus célèbre d'entre elles est la suivante :
string ne commence pas par une majuscule alors que c'est un objet !
Il faut croire que les créateurs de string ne respectaient pas cette convention. Mais
rassurez-vous, maintenant la plupart des gens mettent une majuscule au début de leurs objets
(moi y compris, ce ne sera donc pas la foire dans la suite de ce cours).
En réalité, lorsque vous serez habitué à penser avec des objets, vous verrez qu'une telle
distinction n'est pas nécessaire. Il y a bien d'autres manières de distinguer les types des
variables des types des objets. La première étant la façon dont les objets sont utilisés.
Initialisez la chaîne lors de la déclaration
Pour initialiser notre objet au moment de la déclaration (et donc lui donner une valeur), il y a plusieurs
possibilités.
La plus courante consiste à ouvrir des parenthèses comme nous l'avons fait jusqu'ici :
cpp
1 int main()
2 {
6 return 0;
7 }
C'est la technique classique que l'on connaît déjà, et qui s'applique aussi bien aux variables qu'aux
objets. On dit que l'on construit l'objet.
Et comme pour les variables, il faut noter que l'on peut aussi initialiser avec le signe égal :
string maChaine = "Bonjour !";
On peut l'afficher comme n'importe quelle chaîne de caractères avec un cout :
cpp
1 int main()
2 {
7 return 0;
8 }
Bonjour !
1 int main()
2 {
9 return 0;
10 }
Bonjour !
Bien le bonjour !
Tout cela, vous savez déjà le faire. Ce que je veux vous montrer ici, c'est comment la magie de la POO
opère :
1. Vous, l'utilisateur, vous avez appuyé sur un bouton pour dire : Je veux maintenant que la chaîne à
l'intérieur devienne "Bien le bonjour !".
2. À l'intérieur de l'objet, des mécanismes (des fonctions) se sont activés lorsque vous avez réalisé
l'opération. Ces fonctions ont vérifié, entre autres, s'il y avait de la place pour stocker la chaîne
dans le tableau de char .
3. Elles ont vu que non. Elles ont alors créé un nouveau tableau de char , suffisamment long
cette fois, pour stocker la nouvelle chaîne.
4. Et, tant qu'à faire, elles ont détruit l'ancien tableau qui ne servait plus à rien, puis les nouvelles
lettres ont été copiées.
Mais permettez-moi de vous parler franchement : ce qui s'est passé à l'intérieur de l'objet, on s'en fiche
royalement ! C'est bien là tout l'intérêt de la POO : l'utilisateur n'a pas besoin de comprendre comment
cela fonctionne à l'intérieur. On se moque de savoir que le texte est stocké dans un tableau de char
(ou est-ce un vector ?). L'objet est en quelque sorte intelligent et gère tous les cas. Nous, nous
nous contentons de l'utiliser.
Imaginez que l'on souhaite concaténer (assembler) deux chaînes. En théorie, c'est compliqué à faire car
il faut fusionner deux tableaux de char . En pratique, la POO nous évite de nous soucier du
fonctionnement interne :
cpp
1 int main()
2 {
5 string chaine3;
10 return 0;
11 }
Bonjour !Comment allez-vous ?
À L'affichage, il manque une espace au milieu. On n'a qu'à changer la ligne de la concaténation :
cpp
Résultat :
Bonjour ! Comment allez-vous ?
C'est très simple à utiliser alors que "derrière", ça s'active pour assembler les deux tableaux de char .
On peut comparer des chaînes entre elles à l'aide des symboles == (identique) ou != (différent)
dans un if :
cpp
1 int main()
2 {
7 {
9 }
10 else
11 {
13 }
14
15 return 0;
16 }
Les chaines sont differentes.
À l'intérieur de l'objet, la comparaison se fait caractère par caractère entre les deux tableaux de char
(à l'aide d'une boucle qui compare chacune des lettres). Nous, nous n'avons pas à nous soucier de tout
cela : nous demandons à l'objet chaine1 s'il est identique à chaine2 ; il fait des calculs et nous
répond très simplement par un oui ou un non.
Dans la suite du cours, nous allons apprendre comment faire pour écrire de tels objets, où toutes les
opérations complexes sont cachées. Vous pourrez alors utiliser ces boîtes dans d'autres parties de votre
programme, sans avoir à vous soucier ni même à vous rappeler de leur fonctionnement.
Comme tout objet qui se respecte, le type string propose un nombre important d'autres
fonctionnalités qui permettent de faire tout ce dont on a besoin. Voyons les principales.
1. Les variables contenues à l'intérieur des objets sont appelées "attributs". On parle aussi
de variables membres.
2. Les fonctions sont appelées "méthodes". On parle aussi de fonctions membres.
Imaginez que chaque méthode (fonction) que propose un objet corresponde à un bouton différent sur la
face avant du cube. Pour appeler la méthode d'un objet, on utilise une écriture que vous avez déjà vue :
objet.methode() . On sépare le nom de l'objet et le nom de la méthode par un point.
Cela signifie :
Traduction : "Sur le cube indiqué, j'appuie sur ce bouton pour déclencher une action".
En théorie, on peut aussi accéder aux variables membres (les attributs) de l'objet de la même
manière. Cependant, en POO, il y a une règle très importante : l'utilisateur ne doit pas pouvoir
accéder aux variables membres, mais seulement aux fonctions membres (les méthodes). On en
reparlera plus en détail juste après ce chapitre.
Je vous avais dit qu'il était facile de distinguer les objets des variables car on les utilisait
différemment. Voici donc un premier exemple. La notation avec le point pour appeler une
méthode de l'objet est propre aux objets. On ne peut pas faire ça avec les variables.
La méthode size()
Vous le savez déjà, la méthode size() permet de connaître la longueur de la chaîne actuellement
stockée dans l'objet de type string .
Cette méthode ne prend aucun paramètre et renvoie la longueur de la chaîne. Vous venez de découvrir
qu'il s'agit d'une règle générale, mais nous l'avions déjà fait avant ; il faut appeler la méthode de la
manière suivante :
cpp
1 maChaine.size()
Essayons cela dans un code complet qui affiche la longueur d'une chaîne de caractères :
cpp
1 int main()
2 {
6 return 0;
7 }
Longueur de la chaine : 9
La méthode erase()
1 int main()
2 {
4 chaine.erase();
5 cout << "La chaine contient : " << chaine << endl;
7 return 0;
8 }
La chaine contient :
La méthode substr()
Cette méthode permet d'extraire une partie de la chaîne stockée dans une string .
substr signifie "substring", soit "sous-chaîne" en français.
Tenez, on va regarder son prototype, vous allez voir que c'est intéressant :
cpp
Elle prend deux paramètres ou, plus exactement, un paramètre obligatoire et un paramètre facultatif. En
effet, num possède une valeur par défaut ( npos ), ce qui fait que le second paramètre ne doit pas
obligatoirement être renseigné.
1. index permet d'indiquer à partir de quel caractère on doit couper (ce doit être un numéro de
caractère).
2. num permet d'indiquer le nombre de caractères que l'on prend. Par défaut, la valeur est npos
, ce qui revient à prendre tous les caractères qui restent. Si vous indiquez 2, la méthode ne
renverra que 2 caractères.
1 int main()
2 {
6 return 0;
7 }
jour !
On a demandé à couper à partir du troisième caractère, soit la lettre "j" (étant donné que la première
lettre correspond au caractère n° 0).
On a volontairement omis le second paramètre facultatif, ce qui fait que substr() a renvoyé tous les
caractères restants jusqu'à la fin de la chaîne.
Essayons de renseigner le paramètre facultatif pour exclure le point d'exclamation, par exemple :
cpp
1 int main()
2 {
6 return 0;
7 }
jour
Bingo ! On a demandé à prendre 4 caractères en partant du caractère n° 3, ce qui fait qu'on a récupéré
"jour".
Il existe une autre manière de faire pour accéder à un seul caractère. On utilise les crochets
[ ] comme pour les tableaux.
cpp
En résumé
La programmation orientée objet est une façon de concevoir son code. On considère qu'on
manipule des objets.
Les objets sont parfois complexes à l'intérieur, mais leur utilisation nous est volontairement
simplifiée. C'est un des avantages de la programmation orientée objet.
Un objet est constitué d'attributs et de méthodes, c'est-à-dire de variables et de fonctions
membres.
On appelle les méthodes de ces objets pour les modifier ou obtenir des informations.
La gestion du texte en mémoire est en fait complexe. Pour nous simplifier les choses, le langage
C++ nous propose le type string . Grâce à lui, nous pouvons créer des objets de type
string et manipuler du texte sans avoir à nous soucier du fonctionnement de la mémoire.
Vous venez de découvrir le monde de la programmation orientée objet, et je pense que tout n’est pas
encore clair pour vous. Nous allons sans tarder créer votre première classe, rien de mieux que de
pratiquer pour comprendre. Vous êtes prêt ?
Mentorat individuel
Les professeurs
Mathieu Nebra
Entrepreneur à plein temps, auteur à plein temps et co-fondateur d'OpenClassrooms :o)
Ranga Gonnage
Développeur logiciel, mentor et enseignant.
OPENCLASSROOMS
OPPORTUNITÉS
AIDE
EN PLUS
Français