Vous êtes sur la page 1sur 14

JN

Accueil
> Cours
> Programmez en orienté objet avec C++
> Découvrez la notion de POO

Programmez en orienté objet avec C++

10 heures  Difficile

Mis à jour le 10/02/2022

 

Découvrez la notion de POO

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.

Comprenez d'abord le fonctionnement de   string


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 ?

Oui ! Mais le type  string  est différent des autres. 


int   ,  bool   ,  float   ,  double  sont des types qui stockent des données très
simples.

Ce n'est pas le cas de  string  qui est en fait... un objet !

Je vais vous montrer comment fonctionne  string  "à l'intérieur du cube". Préparez-vous à d'horribles
vérités.

Horrible vérité n° 1 : Pour un ordinateur, les lettres n'existent pas…


L'avantage des objets est de masquer la complexité du code à l'utilisateur. Et justement, les choses sont
compliquées parce que, à la base, un ordinateur ne sait pas gérer du texte ! Oui, l'ordinateur n'est
véritablement qu'une grosse machine à calculer dénuée de sentiments. Il ne reconnaît que des nombres.

Mais alors, si l'ordinateur ne peut manipuler que des nombres, comment se fait-il qu'il puisse
afficher du texte à l'écran ?

Grâce à une astuce que l'on utilise depuis longtemps !

La table ASCII (American Standard Code for Information Interchange) est un tableau qui sert de


convention pour convertir des nombres en lettres.

Nombre Lettre Nombre Lettre

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

Comme vous le voyez :

la lettre « A » majuscule correspond au nombre   ;


la lettre « a » minuscule correspond au nombre   ;
etc.

Tous les caractères utilisés en anglais figurent dans cette table.

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".

Le type  char   (abréviation de "character", caractère, en français) est prévu pour stocker un


caractère. Il stocke donc un nombre qui est interprété comme un caractère.

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...

Horrible vérité n° 2 : Les textes sont des tableaux de   char


Puisque  char  ne peut stocker qu'une seule lettre, les programmeurs ont eu l'idée de créer... un
tableau de  char   ! Mais ça, vous le saviez déjà.

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.

On parle aussi de "chaînes de caractères", vous comprenez maintenant pourquoi.

Ainsi, il suffit de :

déclarer un tableau de  char  pour pouvoir stocker du texte (environ 100 caractères) :
cpp

1 char texte[100];

ou utiliser un   vector   si on veut changer la longueur du texte :

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.

En théorie, on pourrait se débrouiller avec des tableaux statiques ou dynamiques de  char  à


chaque fois que l'on veut manipuler du texte. Mais ce serait fastidieux. C'est pour ça que les
concepteurs du langage ont décidé de cacher tout ces mécanismes dans une boîte fermée, un
objet.

Gérer du texte n'est pas vraiment simple. Il faut :

créer un tableau de  char  dont chaque case correspond à un caractère ;

prévoir une taille suffisante pour stocker le texte que l'on souhaite sinon cela plante...

Bref, cela fait beaucoup de choses auxquelles il faut penser.

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   .

Créez un objet  string



Vous le savez déjà, la création d'un objet ressemble beaucoup à la création d'une variable classique
comme  int  ou  double   :

cpp

1 #include <iostream>
2 #include <string> // Obligatoire pour pouvoir utiliser les objets string

4 using namespace std;

7 int main()

8 {

9 string maChaine; //Création d'un objet 'maChaine' de type string

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.

Intéressons-nous maintenant à la ligne où je crée un objet de type  string   ...

Donc... on crée un objet de la même manière qu'on crée une variable ?

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 !

Mais... comment on fait pour différencier les objets des variables ?

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 :

le type des variables commence par une minuscule (ex. : int) ;


le type des objets commence par une majuscule (ex. : Voiture).

Je sais ce que vous allez me dire :

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 {

3 string maChaine("Bonjour !");

4 //Création d'un objet 'maChaine' de type string et initialisation

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 a maintenant créé un objet  maChaine  qui contient la chaîne "Bonjour !".

On peut l'afficher comme n'importe quelle chaîne de caractères avec un  cout   :

cpp

1 int main()

2 {

3 string maChaine("Bonjour !");

4 cout << maChaine << endl;

5 //Affichage du string comme si c'était une chaîne de caractères

7 return 0;

8 }

Bonjour !

Affectez une valeur à la chaîne après déclaration


Maintenant que notre objet est créé, ne nous arrêtons pas là. Changeons le contenu de la chaîne après
sa déclaration :
cpp

1 int main()

2 {

3 string maChaine("Bonjour !");

4 cout << maChaine << endl;

6 maChaine = "Bien le bonjour !";

7 cout << maChaine << endl;

9 return 0;

10 }

Bonjour !

Bien le bonjour !

Pour changer le contenu d'une chaîne après sa déclaration, on doit obligatoirement utiliser le


symbole  =   .

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.

Assemblez des chaînes de caractères


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 {

3 string chaine1("Bonjour !");

4 string chaine2("Comment allez-vous ?");

5 string chaine3;

7 chaine3 = chaine1 + chaine2; // 3... 2... 1... Concaténatioooooon

8 cout << chaine3 << endl;

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

1 chaine3 = chaine1 + " " + chaine2;

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   .

Comparez des chaînes de caractères


On peut comparer des chaînes entre elles à l'aide des symboles  ==  (identique) ou  !=  (différent)

dans un  if  :
cpp

1 int main()

2 {

3 string chaine1("Bonjour !");

4 string chaine2("Comment allez-vous ?");

6 if (chaine1 == chaine2) // Faux

7 {

8 cout << "Les chaines sont identiques." << endl;

9 }

10 else

11 {

12 cout << "Les chaines sont differentes." << endl;

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.

Faites des opérations sur les   string


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.

Retenez le vocabulaire de base en POO : "Attribut" et "méthode"

Je vous avais dit qu'un objet était constitué de variables et de fonctions.

En fait, le vocabulaire est un peu différent avec les objets :

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 :

"Sur l'objet indiqué, j'appelle cette méthode".

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.

Utilisez les méthodes du type  string

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 {

3 string maChaine("Bonjour !");

4 cout << "Longueur de la chaine : " << maChaine.size();

6 return 0;

7 }

Longueur de la chaine : 9

La méthode  erase()

Cette méthode très simple supprime tout le contenu de la chaîne :


cpp

1 int main()

2 {

3 string chaine("Bonjour !");

4 chaine.erase();

5 cout << "La chaine contient : " << chaine << endl;

7 return 0;

8 }

La chaine contient :

Comme on pouvait s'y attendre, la chaîne ne contient plus rien.

Notez que c'est équivalent à  chaine = "";   .

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

1 string substr( size_type index, size_type num = npos );

Cette méthode renvoie donc un objet de type  string   .

Ce sera la sous-chaîne obtenue après découpage.

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é.

Voyons plus en détail ce qui se cache sous ces paramètres :

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.

Allez, un exemple sera plus parlant, je crois :


cpp

1 int main()

2 {

3 string chaine("Bonjour !");

4 cout << chaine.substr(3) << endl;

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 {

3 string chaine("Bonjour !");

4 cout << chaine.substr(3, 4) << endl;

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

1 string chaine("Bonjour !");

2 cout << chaine[3] << endl; //Affiche la lettre 'j'

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 ?

J'ai terminé ce chapitre et je passe au suivant

Et si vous obteniez un diplôme OpenClassrooms ?

Formations jusqu’à 100 % financées

Date de début flexible


Projets professionnalisants

Mentorat individuel

Trouvez la formation et le financement faits pour vous

Être orienté Comparez nos types de formation

 Tirez un maximum de ce cours Créez une classe 

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

POUR LES ENTREPRISES

EN PLUS

Français
 

Vous aimerez peut-être aussi