Vous êtes sur la page 1sur 95

LA PROGRAMMATION ORIENTÉE OBJET

NOTES NUMÉRIQUES

B.TECH
(I AN - II SEM)
(2018-19)

DÉPARTEMENT CSE & IT

LNVETOLEARN&LEARNTO

MALLA REDDY COLLEGE OF ENGINEERING & TECHNOLOGY


(Autonomous Institution - UGC, Govt. of India)
Reconnu sous 2(f) et 12 (B) de l'UGC ACT 1956 (Affilié à JNTUH, Hyderabad, Approuvé par AICTE -
Accrédité par NBA & NAAC - Grade 'A' - Certifié ISO 9001:2015) Maisammaguda, Dhulapally (Post Via.
Hakimpet), Secunderabad - 500100, État de Telangana, Inde.

I Année B.Tech II L T/P/D C


SEM 4 1/-/- 3
(R18A0502)PROGRAMMATION ORIENTÉE OBJET

Objectifs
• Enseigner à l'étudiant les concepts de la programmation orientée objet et de la
programmation par procédures.
• Différencier les fonctions, les classes et les objets
• Apprendre à surcharger les fonctions et les opérateurs
• Concevoir des applications utilisant des techniques de gestion dynamique de la mémoire
• Apprendre à l'étudiant à mettre en œuvre la programmation générique et la gestion des
exceptions.

Unité I
Introduction à la programmation orientée objet : Paradigme orienté objet - Différences entre la
programmation orientée objet et la programmation orientée procédure, concepts de base de la
programmation orientée objet, encapsulation, héritage et polymorphisme, avantages de la POO,
structure d'un programme C++, espace de noms, types de données, jetons C++, identificateurs,
variables, constantes, opérateurs, structures de contrôle et boucles.

Unité II
Fonctions, classes et objets :
Introduction des classes, définition des classes, définition des membres, objets, contrôle d'accès,
portée de la classe, opérateur de résolution de portée, fonctions en ligne, allocation de mémoire
pour les objets, membres statiques des données, fonctions statiques des membres, tableaux d'objets,
objets en tant qu'arguments de fonction, fonctions amies.

Unité III
Constructeurs, destructeurs, héritage :
Introduction aux constructeurs, aux constructeurs par défaut, aux constructeurs paramétrés, aux
constructeurs par copie, aux constructeurs multiples dans une classe, aux destructeurs.
Héritage :
Introduction à l'héritage, définition des classes dérivées, héritage simple, héritage multiple, héritage
à plusieurs niveaux, héritage hiérarchique, héritage hybride.

Unité IV
Pointeurs, fonctions virtuelles et polymorphisme :
Introduction à la gestion de la mémoire, nouveaux opérateurs et opérateurs de suppression,
pointeurs sur les objets, pointeurs sur les classes dérivées, polymorphisme, polymorphisme au
moment de la compilation, polymorphisme au moment de l'exécution, fonctions virtuelles, surcharge
- surcharge de fonctions, surcharge d'opérateurs.

Unité V
Modèles et gestion des exceptions :
Introduction aux modèles, modèles de classes, modèles de classes avec paramètres multiples,
modèles de fonctions, modèles de fonctions avec paramètres multiples.
Gestion des exceptions :
Principes de base de la gestion des exceptions, types d'exceptions, mécanisme de gestion des
exceptions, mécanisme de renvoi et de capture, renvoi d'une exception, spécification des exceptions.

Résultats :
• Différencier la programmation orientée objet de la programmation procédurale.
• Construire des classes, des fonctions et des objets
• Pour mettre en œuvre les constructeurs, les destructeurs et l'héritage
• Développer des programmes utilisant des techniques de gestion dynamique de la mémoire
• Appliquer la gestion des exceptions et la programmation générique.

Livres de cours :
1. Programmation orientée objet avec C++ par Balagurusamy
2. C++, la référence complète,4e édition, Herbert Schildt, TMH.

Références :
1. C++ Primer,3ème édition, S.B.Lippman et J.Lajoie, Pearson Education.
2. Le langage de programmation C++,3e édition, B.Stroutstrup, Pearson Educ
UNITÉ -1

Concepts de la programmation orientée objet : Paradigme orienté objet - différences entre la


programmation orientée objet et la programmation orientée procédure, concepts de base de la programmation
orientée objet, encapsulation, héritage et polymorphisme. Structure d'un programme C++, espace de noms,
types de données, jetons C++, identificateurs, variables, constantes, opérateurs, structures de contrôle et
boucles.

Vue d'ensemble du langage C :


1. Le langage C est connu comme un langage orienté structure ou un langage orienté procédure.
2. Emploie une approche de programmation descendante dans laquelle un problème est considéré comme une
séquence de tâches à effectuer.
3. Tout le code de programme de c peut être exécuté en C++, mais l'inverse n'est pas toujours possible.
4. La surcharge des fonctions et la surcharge des opérateurs ne sont pas possibles.
5. Les variables locales ne peuvent être déclarées qu'au début du bloc.
6. Les contrôles du programme se font par des sauts et des appels à des sous-programmes.
7. Le polymorphisme, l'encapsulation et l'héritage ne sont pas possibles.
Pour résoudre les problèmes, le problème est divisé en plusieurs modules. Chaque module est un sous-
programme.
8. La propriété d'abstraction des données n'est pas prise en charge par les langages orientés procédures.
9. Dans un langage orienté procédure, les données sont ouvertes et peuvent être consultées par n'importe quelle
fonction.

Vue d'ensemble du langage C++ :


1. Le C++ peut être considéré comme une version incrémentale du langage C qui comprend toutes les
constructions du langage de programmation avec des caractéristiques nouvellement ajoutées de la programmation
orientée objet.
2. C++ est un langage de programmation orienté structure (procédure) et objet.
3. L'extension de fichier du programme C++ est ".CPP"
4. La surcharge des fonctions et la surcharge des opérateurs sont possibles.
5. Les variables peuvent être déclarées en ligne, c'est-à-dire lorsque cela est nécessaire.
6. En c++, l'accent est mis sur les données plutôt que sur les procédures.
7. Le polymorphisme, l'encapsulation et l'héritage sont possibles.
8. La propriété d'abstraction de données est prise en charge par c++.
9. L'accès aux données est limité. Il est possible d'y accéder en proposant différents modes de visibilité pour les
données et les fonctions membres, et en assurant la sécurité des données par leur dissimulation.
10. La liaison dymanique est prise en charge par C++.
11. Il prend en charge toutes les fonctionnalités du langage c
12. il peut être considéré comme une version incrémentale du langage c
Différence entre la programmation orientée procédure (POP) et la programmation orientée objet (POO)

Programmation axée sur les procédures Programmation orientée objet


est divisé en petites parties appelées
1
est divisé en parties appelées objets.
fonctions.
L'importance n'est pas accordée aux données L'importance est accordée aux données plutôt
2
mais aux fonctions ainsi qu'à la séquence qu'aux procédures ou aux fonctions, car elles
d'actions à effectuer. fonctionnent comme dans le monde réel.
3 suit une approche descendante. La POO suit une approche ascendante.
La POO dispose de spécificateurs d'accès appelés
4 Il n'a pas de spécificateur d'accès.
Public, Private, Protected, etc.
Les données peuvent circuler librement d'une Les objets peuvent se déplacer et communiquer
5
fonction à l'autre dans le système. entre eux par le biais de fonctions membres.
Il n'est pas facile d'ajouter de nouvelles données La POO permet d'ajouter facilement de nouvelles
6
et fonctions dans POP. données et fonctions.
La plupart des fonctions utilisent des données Dans la POO, les données ne peuvent pas se
7 globales pour le partage qui peuvent être déplacer facilement d'une fonction à l'autre, elles
consultées librement d'une fonction à l'autre peuvent rester publiques ou privées, ce qui permet
dans le système.
Il ne dispose d'aucun moyen approprié pour de
La contrôler
POO permetl'accès aux données.
de masquer les données et offre
8
dissimuler les données et est donc moins sûr. donc une plus grande sécurité.
Dans la POO, la surcharge est possible sous la
9 La surcharge n'est pas possible. forme de surcharge de fonction et de surcharge
d'opérateur.
Exemple de procédure orientée
Les exemples de programmation orientée objet
10 Les programmes sont : C, VB, FORTRAN, sont : C++, JAVA, VB.NET, C#.NET.
Pascal.

Principes (ou caractéristiques) de la programmation orientée objet :


1. Encapsulation
2. Abstraction de données
3. Polymorphisme
4. Héritage
5. Liaison dynamique
6. Passage de messages
Encapsulation : L'encapsulation consiste à regrouper des données et des fonctions en une seule unité. Par défaut,
les données ne sont pas accessibles au monde extérieur et ne le sont que par l'intermédiaire des fonctions qui sont
intégrées dans une classe. La prévention de l'accès direct aux données par le programme est appelée dissimulation
de données ou dissimulation d'informations.

Abstraction de données :
L'abstraction consiste à représenter les caractéristiques essentielles sans inclure les détails ou
les explications de fond. Les classes utilisent le concept d'abstraction et sont définies comme une liste d'attributs
tels que la taille, le poids, le coût et les fonctions permettant d'opérer sur ces attributs. Ils encapsulent toutes les
propriétés essentielles de l'objet à créer. Les attributs sont appelés membres de données car ils contiennent des
données et les fonctions qui opèrent sur ces données sont appelées fonctions membres.
Les classes utilisent le concept d'abstraction de données et sont donc appelées types de données abstraits
(ADT).

Polymorphisme : Le polymorphisme vient des mots grecs "poly" et "morphisme". Le mot "poly" signifie
"beaucoup" et le mot "morphisme" signifie "forme", c'est-à-dire "plusieurs formes". Le polymorphisme est la
capacité de prendre plus d'une forme. Par exemple, une opération a un comportement différent selon les cas. Le
comportement dépend du type de données utilisées dans l'opération.
Différentes façons de réaliser le polymorphisme dans un programme C++ :
1) Surcharge des fonctions 2) Surcharge des opérateurs
#include<iostream>
en utilisant l'espace de noms
std ; int main() {inta=4 ; a=a<<2 ;
cout<<"a="<<a<<endl ;
retour 0 ;
}

L'héritage : L'héritage est le processus par lequel un objet peut acquérir les propriétés d'un autre.
L'héritage est le concept le plus prometteur de la POO, qui permet de réaliser l'objectif de construire des logiciels
à partir d'éléments réutilisables, plutôt que de coder à la main chaque système à partir de zéro. L'héritage permet
non seulement la réutilisation entre systèmes, mais facilite aussi directement l'extensibilité à l'intérieur d'un
système. L'héritage, associé au polymorphisme et à la liaison dynamique, minimise la quantité de code existant à
modifier tout en améliorant un système.
Lorsque la classe enfant hérite de la classe parent, la classe enfant est appelée classe dérivée (sous-classe)
et la classe parent est appelée classe de base (super-classe). Dans ce cas, la classe enfant comporte deux parties :
une partie dérivée et une partie incrémentale. La partie dérivée est héritée de la classe mère. La partie
incrémentale est le nouveau code écrit spécifiquement pour la classe enfant.
Liaison dynamique :
La liaison fait référence au lien entre l'appel de procédure et le code à exécuter en réponse à l'appel. La
liaison dynamique (ou liaison tardive) signifie que le code associé à un appel de procédure donné n'est pas connu
avant le moment de l'appel au moment de l'exécution.

Passage de messages :
Un programme orienté objet se compose d'un ensemble d'objets qui communiquent entre eux.
Les objets communiquent entre eux en envoyant et en recevant des informations.
Un message pour un objet est une demande d'exécution d'une procédure et donc d'invocation de la
fonction qui est appelée pour un objet et qui génère un résultat.

Avantages de la programmation orientée objet (POO)


> , ........................... . . , , ,, Réutilisation : Dans les programmes OOP, les fonctions et les modules écrits par un utilisateur
peuvent être réutilisés par d'autres utilisateurs sans aucune modification.
L'héritage: Il permet d'éliminer le code redondant et d'étendre l'utilisation des classes existantes.
Masquage des données : Le programmeur peut cacher les données et les fonctions d'une classe aux autres classes. Il aide le
programmeur à élaborer des programmes sûrs.
Réduction de la complexité d'un problème : le problème donné peut être considéré comme une collection d'objets
différents. Chaque objet est responsable d'une tâche spécifique. Le problème est résolu par l'interfaçage des objets. Cette
technique réduit la complexité de la conception du programme.

Facilité de maintenance et de mise à jour: La POO facilite la maintenance et la modification du code existant car
de nouveaux objets peuvent être créés avec de petites différences par rapport aux objets existants. La complexité des
logiciels peut être facilement gérée.
Passage de messages : La technique de communication par messages entre objets facilite l'interface avec les systèmes externes.

Modifiabilité : il est facile d'apporter des modifications mineures à la représentation des données ou aux
procédures d'un programme OO. Les changements à l'intérieur d'une classe n'affectent aucune autre partie
d'un programme, puisque la seule interface publique que le monde extérieur a avec une classe est
l'utilisation de méthodes.

STRUCTURE DE BASE DU LANGAGE C++ : Le programme écrit en langage C++ suit cette structure de
base. L'ordre des sections doit être le même que dans la structure de base. Un programme C peut comporter une
ou plusieurs sections, mais l'ordre des sections doit être respecté.
1. Section documentation
2. Section de liaison
3. Section de définition
4. Section de déclaration globale et déclarations de classe
5. Définition des fonctions membres
6. Fonction principale
section main() {
Section de la déclaration Section exécutable
1. SECTION DE DOCUMENTATION : elle vient en premier et sert à documenter l'utilisation de la
logique ou des raisons dans votre programme. Il peut être utilisé pour écrire l'objectif du programme, le
développeur et les détails de la logique. La documentation est réalisée en langage C avec /* et */ . Tout ce qui est
écrit entre les deux est appelé commentaire.
2. SECTION DE LIAISON : Cette section indique au compilateur de lier certaines occurrences
de mots-clés ou de fonctions de votre programme aux fichiers d'en-tête spécifiés dans cette section.
Par exemple, #include<iostream>
using namespace std ;
fait en sorte que le préprocesseur ajoute le contenu du fichier iostream au programme. Il contient des déclarations pour cout et cin.
>
cout est un objet prédéfini qui représente le flux de sortie standard. L'opérateur << est un
l'opérateur d'insertion, provoque l'affichage à l'écran de la chaîne de caractères entre guillemets.

L'instruction cin>>n ; est une instruction d'entrée et fait en sorte que le programme attende que l'utilisateur tape
un nombre. Le nombre saisi est placé sur la variable "n". L'identifiant cin est un objet prédéfini en C++ qui
correspond au flux d'entrée standard. L'opérateur >> est appelé opérateur d'extraction. Il extrait la valeur du
clavier et l'affecte à la variable value située à sa droite.

3. SECTION DE DÉFINITION : Elle est utilisée pour déclarer certaines constantes et leur
assigner un certain nombre d'éléments.
valeur, par exemple #define MAX 25
Ici, #define est une directive du compilateur qui indique au compilateur de remplacer MAX par 25
chaque fois qu'il se trouve dans le programme.
4. SECTION DE DÉCLARATION GLOBALE : Ici, les variables et les définitions de classes utilisées
dans tout le programme (y compris la fonction principale et les autres fonctions) sont déclarées de manière à les
rendre globales (c'est-à-dire accessibles à toutes les parties du programme). Un CLASS est un ensemble de
données et de fonctions qui agissent ou manipulent les données. Les composants de données d'une classe sont
appelés membres de données et les composants de fonctions d'une classe sont appelés fonctions membres.
Une classe est également considérée comme un modèle ou un prototype qui définit les variables ou les
fonctions communes à tous les objets d'un certain type. Il s'agit d'un type de données défini par l'utilisateur

par exemple

int i ; //cette déclaration est faite à l'extérieur et avant main()

5. SECTION DES SOUS-PROGRAMMES OU DES FONCTIONS : elle contient tous les sous-
programmes ou les fonctions dont notre programme a besoin.

void display()
{
cout<<"C++ est meilleur que C" ;
}
PROGRAMME "C++" SIMPLE :
#include<iostream>
using namespace std ;
void display()
{
cout<<"C++ est meilleur que C" ;
}
int main()
{
afficher()
retour 0 ;
}

6. SECTION DE LA FONCTION PRINCIPALE : Elle indique au compilateur où commencer l'exécution


à partir de main().
{
point de départ de l'exécution
}
La fonction principale comporte deux sections
1. section de déclaration : cette section permet de déclarer les variables et leurs types de données.
2. Section exécutable ou section d'instructions : il s'agit de la partie du programme qui exécute
effectivement la tâche dont nous avons besoin.

l'espace de noms :
est utilisé pour définir une portée qui pourrait contenir des identificateurs globaux.
ex:-l'espace de noms de la bibliothèque standard c++.
Les classes, fonctions et modèles sont déclarés dans l'espace de noms nommé
std using namespace std;-->directive peut être utilisée.

l'espace de noms défini par l'utilisateur :


La syntaxe pour définir l'espace de noms est la suivante

nom de l'espace de noms nom de l'espace de noms


{
//déclarations de variables, fonctions, classes, etc...
}
ex :
#include<iostream>
using namespace std ;
espace de noms sample
{`
int m ;
void display(int n)
{
cout<"in namespace N="<<n<<endl ;
}
}

en utilisant l'espace de noms sample ;


int main()
{
int a=5 ;
m=100 ;
affichage(200) ;
cout<<"M dans l'espace de noms de l'échantillon :"<<échantillon::m ;
return 0;}

#include<iostream>
Cette directive oblige le préprocesseur à ajouter le contenu du fichier iostream au programme. Certaines
anciennes versions de C++ utilisaient iostream.h. Si le compilateur ne supporte pas le C++ ANSI
(american nation standard institute), utilisez le fichier d'en-tête iostream.h.
TYPES DE DONNÉES :
Un type de données est utilisé pour indiquer le type de valeur de données stockée dans une variable. Tous
les compilateurs C prennent en charge une grande variété de types de données. Cette variété de types de
données permet au programmeur de sélectionner le type approprié aux besoins de l'application et de la
machine. ANSI C prend en charge les classes de données suivantes

Types de données primaires :


1. type de données entières
2 Type de données .character
3 Type de données .float
4 Type de données booléen
5. type de données void
type de données entier:-
Ce type de données est utilisé pour stocker des nombres entiers. Ces nombres ne contiennent pas de partie décimale. La taille
de l'entier dépend de la longueur du monde d'une machine (16 bits ou 32 bits). Sur une machine 16 bits, la plage des valeurs
entières est comprise entre - 32 768 et +32 767. Les variables entières sont déclarées par le mot-clé int. Le langage C permet
de contrôler la plage des valeurs entières et l'espace de stockage occupé par ces valeurs grâce aux types de données : short
int, int, long int, sous forme signée ou non.

Entiers signés : (machine 16 bits) :


Un nombre entier signé utilise 1 bit pour le signe et 15 bits pour la magnitude du nombre.
Un nombre entier signé utilise 1 bit pour le signe et 15 bits pour la magnitude du nombre. ( -215à +215-1).
Ex : signé tx=100 ;
0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0

, । । .......Bit signé Ampleur


MSB (bit le plus significatif)
100(10)=00000000001100100(2)
Représentation d'un nombre négatif :

-100(10)=1111111110011100(2)

15 14 13 12 11 10 9 8 7 -1*2 +1*2 +1*2 +1*2 +1*2 +1*2 +1*2 +1*2


+1*2 +
6 5 4 3 2 1 0
0*2 +0*2 +1*2 +1*2 +1*2 +0*2 +0*2
= -32768+16384+8192+4096+2048+1024+512+256+128+0+0+26+8+4+0+0 =-
100(10)
NOTE : Bit signé (MSB BIT): 0 représente un nombre entier positif, 1 représente un nombre négatif.

Les entiers non signés: Les entiers non signés utilisent les 16 bits pour stocker la magnitude. Les nombres stockés
n'ont pas de signe et le qualificateur de taille et la plage du type de données entières sur une machine 16 bits sont
indiqués dans le tableau :
MÉMOIRE REQUISE
GAMME
TYPE DE OU LA TAILLE DE LA FORMAT
DONNÉES MÉMOIRE
TURBO C EN OCTETS GCC/ TURBO C ( 16 BIT) CCG SPECIER
( 16 BIT) COMPILATEURS (32 BIT)
SOUS LINUX (32 BIT)
court int
-32768
ou -32768
2 2 Jusqu'à 32767 %hd
Jusqu'à 32767 (-2 à +2
short int signé -1) (-2 à +2 -1)
court int
0 à 65535 (0 à +2 -1) 0 à 65535 (0 à +2 -1)
ou short
int signé 2 2 %hu

-32768 -2.147.843.648 à
2 4
Jusqu'à 32767 (-2 à +2 2.147.843.647 (-2 à +2
int signé ou int %d ou %i
-1) -1)
unsigned int 0 à 65535 0 à 4 294 967 295 (0 à2 -1 )
2 4 (0 à +2 -1) %u
long int ou signed
long int -2 147 843 648 à -2 147 843 648 à
4 4 2,147,843,647 2,147,843,647 %ld
31 31
(-2 à +2 -1) (-2 à +2 -1)
unsigned long int 0 à 4 294 967 295 0 à 4 294 967 295 (0 à2 -1 )
4 4 (0 à2 -1 ) %lu
long long int ou -9223372036854775808
signé long long Pour
Non pris en
charge 8 ------- 9223372036854775807 (- %Ld
int
263
à +263-1)

Type de données de caractères: (char)


Un seul caractère peut être défini comme un type de données de caractère. Le type de données "caractère" occupe
un octet de mémoire pour le stockage du caractère. Les qualificatifs signed ou unsigned peuvent être appliqués
au type de données char. char est le mot clé utilisé pour déclarer les variables.
la taille et l'étendue du type de données de caractère sur une machine 16 bits ou 32 bits peuvent être indiquées ci-
dessous

Type de données MEMOIRE REQUISE OU GAMME FORMAT SPECIER


TAILLE DE STOCKAGE (en
octets)
char ou char signé 1 -128 à 127(-2 7à 2 -1) %c
Caractère signé non signé 1 0 à 256 (0 à 2 -1) %c

Types à virgule flottante :

Un nombre à virgule flottante représente un nombre réel avec une précision de 6 chiffres et occupe 4 octets de
mémoire.
Les variables à virgule flottante sont déclarées par le mot-clé float.
Le type de données à virgule flottante double occupe 8 octets de mémoire et offre une précision de 14 chiffres.
Ces nombres sont également connus sous le nom de nombres de double précision. Les variables sont déclarées
par le mot-clé double long double fait référence à un type de données à virgule flottante qui est souvent plus précis
que la double précision.
La taille et la plage du type de données à virgule flottante sont indiquées dans le tableau :
Type de données Taille (mémoire) Gamme spécificateur de
(mot clé) format
Flotteur 32 bits (4 octets) 3,4E-38t03,4E+38 %f
Double 64 bits (8 octets) 1.7E-308 à I.7E +308 %lf
long double 80 bits (10 octets) 3.4E-4932 à 1.1E+4932 Lf
B Type de données
oléanes:-
Le type de données booléen ou logique est un type de données ayant deux valeurs (généralement notées true et
false), destiné à représenter les valeurs de vérité de la logique et de l'algèbre booléenne. Elle porte le nom de
George Boole, qui a défini pour la première fois un système algébrique de logique au milieu du 19e siècle. Le
type de données booléen est le principal résultat des instructions conditionnelles, qui permettent différentes
actions et modifient le flux de contrôle selon qu'une condition booléenne spécifiée par le programmeur est
évaluée comme vraie ou fausse.
C99 a ajouté un type booléen (vrai/faux) qui est défini dans l'en-tête <stdbool.h> La variable booléenne est
définie par le mot clé bool ; Ex :

bool b ;
où b est une variable qui peut stocker des valeurs vraies (1) ou fausses (0).

Type de vide
Le type void n'a pas de valeurs. Il est généralement utilisé pour spécifier le type de retour des fonctions. Le type de la
fonction est dit "void" lorsqu'elle ne renvoie aucune valeur à la fonction appelante. Il est également utilisé pour déclarer un
pointeur d'usage général appelé pointeur void.
Types de données dérivées.
Les types de données dérivés sont les tableaux, les pointeurs et les références.
Types de données définis par l'utilisateur :
Les types de données définis par l'utilisateur sont appelés types de données définis par l'utilisateur.
Il s'agit de la structure, de l'union, de la classe et de l'énumération.

Jetons C++
IDENTIFICATEURS : Les identificateurs sont les noms donnés aux différents éléments du programme tels que
les variables, les fonctions et les tableaux. Il s'agit de noms définis par l'utilisateur, constitués d'une séquence de
lettres et de chiffres.
Règles de déclaration des identifiants :
Le premier caractère doit être un alphabet ou un trait de soulignement.
> Il doit être composé uniquement de lettres, de chiffres et de traits de soulignement.
Les identificateurs peuvent avoir n'importe quelle longueur, mais seuls les 31 premiers caractères sont significatifs.
> Il ne doit pas contenir d'espace blanc ou d'espace vierge.
Nous ne devrions pas utiliser de mots-clés comme identifiants.
> Les lettres majuscules et minuscules sont différentes.
Exemple : ab Ab aB AB sont traités différemment
Exemples d'identifiants valides :
a, x, n, num, SUM, fact, grand_total, sum_of_digits, sum1

Exemples d'identifiants non valides: $amount, ³num', grand-total, somme des chiffres, 4num.
$amount: Le caractère spécial n'est pas autorisé
total général: le trait d'union n'est pas autorisé.
somme des chiffres : les espaces entre les mots ne sont pas autorisés.
4num : ne doit pas commencer par un nombre (le premier caractère doit être une lettre ou un trait de
soulignement)

Note : Certains compilateurs C ne reconnaissent que les 8 premiers caractères, ce qui les empêche de distinguer
les identificateurs dont les mots ont une longueur supérieure à 8 caractères.

Variables:Un emplacement mémoire nommé est appelé variable.


OU
Il s'agit d'un identifiant utilisé pour stocker la valeur d'un type de données particulier dans la
mémoire.
Comme le nom de la variable est un identifiant, nous utilisons les règles suivantes, qui sont les mêmes que
pour l'identifiant
Règles de déclaration des noms de
variables
Le:premier caractère doit être un alphabet ou un trait de soulignement.
> Il doit être composé uniquement de lettres, de chiffres et de traits de soulignement.
> Les identificateurs peuvent avoir n'importe quelle longueur, mais seuls les 31 premiers caractères sont significatifs.
Il ne doit pas contenir d'espace blanc ou d'espace vierge.

> Nous ne devrions pas utiliser de mots-clés comme identifiants.


Les lettres majuscules et minuscules sont différentes.
Les noms de variables doivent être uniques dans le champ d'application donné
> Ex:int a,b,a;//est valide
Int a,b;//est valide

Déclaration de variable : La déclaration d'une variable donne le nom de l'emplacement de la mémoire, sa


taille et son
spécifie nom.de valeurs qui peut être stockée dans cet
la plage
Syntaxe :
emplacement.
Nom de la variable de
type de données ; a 10 2000
Ex :
int a=10 ; x 2.300000 5000
float x=2.3
MOTS-CLÉS : ;
Certains mots, appelés mots-clés (mots réservés), ont une signification prédéfinie dans le langage
"C++" . Ces mots-clés ne doivent être utilisés que dans le but pour lequel ils ont été conçus et non comme
identifiants.
Le tableau suivant présente les mots-clés standard "C++".
automobile pause cas char constante continuer
par défaut faire double autre enum externe
flotteur pour goto si int long
registre retour court signé taille de statique
struct interrupteur typedef syndicat non signé vide
volatile alors que classe ami nouveau supprimer
cette public privé protégé en ligne essayer
lancer attraper modèle

CONSTANTS :
Les constantes sont des valeurs qui ne changent pas au cours de l'exécution d'un programme.
Les constantes peuvent être divisées en deux catégories principales :
1.constantes primaires:
a) Constantes numériques
Constantes entières.
Virgule flottante (réel)
b)Constantes de caractères
Constantes de caractère unique Constantes de chaîne
2.Constantes secondaires:
Constantes d'énumération.
Constantes symboliques.
Tableaux, unions, etc.
Règles de déclaration des constantes :
1 Les virgules et les espaces vides ne sont pas autorisés dans la constante.
2 La constante peut être précédée d'un signe moins (-) si nécessaire.
3 La valeur d'une constante doit être comprise dans les limites minimales de son type de données spécifié.
Constantes entières : Une constante entière est un nombre à valeur entière. Il s'agit d'une séquence de chiffres.
Les constantes entières peuvent être écrites dans trois systèmes de numération différents :
1 Entier décimal (base 10).
2 Entier octal (base 8).
3 Hexadécimal (base 16).
Constante entière décimale: elle se compose d'un ensemble de chiffres, de 0 à 9.
Déclaration valide : 0, 124, -56, + 67, 4567 etc.
Déclaration invalide : $245, 2.34, 34 345, 075.
23 345,00. Il s'agit également d'une déclaration non valable.
Note : Les espaces, les virgules, les caractères et les symboles spéciaux ne sont pas autorisés entre les chiffres.

Ils peuvent être précédés d'un signe + ou ± facultatif.

Nombre entier octal: Il se compose d'un ensemble de chiffres, de 0 à 7.


Ex : 037, 0, 0765, 05557 etc. (représentation valide)
Il s'agit d'une séquence de chiffres précédés de 0.
Ex : Représentations non valides
0394 : le chiffre 9 n'est pas autorisé (uniquement les chiffres 0 à 7)
235 : ne commence pas par 0 (le premier chiffre doit être 0).

Entier hexadécimal : Il se compose d'un ensemble de chiffres de 0 à 9 et des alphabets A, B, C, D, E et F.


L'entier hexadécimal est une séquence de chiffres précédés de 0x ou 0X. Nous pouvons également utiliser les
lettres a à f au lieu de A à F.
Ex : 0X2, 0x9F, 0Xbcd, 0x0, 0x1 (représentations valides).
Ex : Représentations non valides : 0af, 0xb3g, 0Xgh.
0af : ne commence pas par 0x ou 0X.
0xb3g, 0Xgh : caractères illégaux tels que g, h. (seuls les caractères a à f sont autorisés)

La magnitude (valeur maximale) d'une constante entière peut aller de zéro à une valeur maximale qui varie d'un
ordinateur à l'autre.
Les valeurs maximales typiques pour la plupart des ordinateurs personnels sont les suivantes : (machines 16 bits)
Constante entière décimale : 32767 (215-1)
Constante entière octale : 077777
Constante entière hexadécimale : 0X7FFF
Remarque : la plus grande valeur pouvant être stockée dépend de la machine.

Constantes à virgule flottante ou constantes réelles : Les nombres comportant des parties fractionnaires sont
appelés constantes réelles.
Il s'agit des nombres en base 10 qui contiennent soit une partie décimale, soit un exposant (ou les deux).
Représentation : Ces nombres peuvent être représentés soit en notation décimale, soit en notation des exposants
(notation scientifique).
Notation décimale : 1234,56, 75,098, 0,0002, -0,00674 (notations valides)
Exposant ou notation scientifique :
Forme générale : Mantisse e exposant
Mantisse : il s'agit d'un nombre réel exprimé en notation décimale ou en notation entière.
Exposant : Il s'agit d'un nombre entier avec un signe plus (+) ou moins (-) optionnel.
E ou e: La lettre qui sépare la mantisse de la partie décimale.
Ex : (Notations valides)
3
1.23456E+3(1.23456×10 )
1
7.5098 e+1(7.5098×10 )
-4
2E-4(2×10 )
Ces notations exponentielles sont utiles pour représenter des nombres qui sont soit très grands, soit très grands.
petit. Ex : 0.00000000987 est équivalent à 9.87e-9

Constantes de caractères:-
Constantes à caractère unique: Il s'agit d'un caractère (ou de tout symbole ou chiffre) placé entre guillemets simples.
Ex : "a" "1" "*
Toutes les constantes de caractères ont des valeurs entières connues sous le nom de valeurs ASCII

ASCII:- ASCII signifie American Standard Code for Information Interchange (code standard américain pour l'échange
d'informations). Prononcé ask-ee, ASCII est un code permettant de représenter les caractères anglais sous forme de nombres,
chaque lettre se voyant attribuer un nombre compris entre 0 et 255.Les ordinateurs ne peuvent comprendre que des nombres,
de sorte qu'un code ASCII est la représentation numérique d'un caractère tel que 'a' ou '@' ou d'une action
. Les codes A SCII représentent le texte dans les ordinateurs, les équipements de communication et d'autres appareils qui
utilisent du texte. La plupart des systèmes modernes de codage des caractères sont basés sur l'ASCII, bien qu'ils prennent en
charge de nombreux caractères supplémentaires. Vous trouverez ci-dessous la table des caractères ASCII, qui comprend la
description des 32 premiers caractères non imprimables.
Constantes de chaîne ou littérales de chaîne :

Une constante de chaîne est une séquence de zéro ou plusieurs caractères entre guillemets.
Exemple :
"MRCET" "12345" "*)(&%"
Séquences d'échappement ou constantes de caractères d'antislash
Le langage C prend en charge certains caractères non imprimables, ainsi que la barre oblique inverse ( \ ) , qui
peuvent être exprimés de la manière suivante
comme séquences d'échappement. Une séquence d'échappement commence toujours par une barre oblique
inverse suivie d'un ou plusieurs caractères spéciaux.
Par exemple, le caractère de retour à la ligne est représenté par "\n" ou endl.
Elles sont utilisées pour formater l'écran de sortie, c'est-à-dire que les séquences d'échappement sont utilisées
dans le cadre de l'application de la loi.
les fonctions de sortie. Quelques séquences d'échappement sont présentées ci-dessous :

Séquence d'échappement Caractère


"a' alerte sonore
"b' espace arrière
"f alimentation du formulaire
"n' nouvelle ligne
"e' onglet horizontal
onglet vertical
guillemet simple
double guillemet
«\23 point d'interrogation
"W Barre oblique inversée
Non' Nul
OPÉRATEURS ET EXPRESSIONS
Un opérateur est un symbole qui représente une opération particulière pouvant être effectuée sur des données. Un opérande
est l'objet sur lequel une opération est effectuée.
En combinant les opérateurs et les opérandes, nous formons une expression. Une expression est une séquence d'opérandes et
d'opérateurs qui se réduit à une seule valeur.

Les opérateurs C peuvent être classés comme suit


1. Opérateurs arithmétiques
2. Opérateurs relationnels
3. Opérateurs logiques
4. Opérateurs d'affectation
5. Opérateurs d'incrémentation ou de décrémentation
6. Opérateur conditionnel
7. Opérateurs de bits
8. opérateur unaire
9. Opérateurs spéciaux
10. Opérateurs supplémentaires en c++

1. OPÉRATEURS ARITHMÉTIQUES : Tous les opérateurs arithmétiques de base sont présents en C.


opérateur sens
+ ajouter
- soustraire
* multiplier
/ division
% division modulo(reste)
Une opération arithmétique impliquant uniquement des opérandes réels (ou des opérandes entiers) est
appelée arithmétique réelle (ou arithmétique des entiers). Si une combinaison d'arithmétique et de réel est appelée
arithmétique en mode mixte.
/*Programme C sur les expressions arithmétiques entières*/
#include<iostraem.h>
void main()
{
int a, b ;
cout<"Entrez deux entiers quelconques" ;
cin>>a>>b ;
cout<<"a+b"<< a+b ;
cout<<"a-b"<< a-b ;
cout<<"a*b"<< a*b ;
cout<<"a/b"<< a/b ;
cout<<"a%b"<< a%b ;
}

SORTIE :
a+b=23
a-b=17
a*b=60
a/b=6
a% b=2

2. OPÉRATEURS RELATIONNELS : Nous comparons souvent deux quantités et, en fonction de leur
relation, nous prenons certaines décisions. Pour cette comparaison, nous utilisons des opérateurs relationnels.
opérateur sens

> est inférieur à


> est supérieur à
> = est inférieur ou égal à
> = est supérieur ou égal à
== est égal à
!= n'est pas égal à
/* Programme C sur les opérateurs relationnels*/
#include<iostream.h>
void main()
{
int a,b ;
clrscr() ;
cout<<"Entrez les valeurs a, b :";
cin>>a>>b ;
cout<<"a>b"<< a>b ;
cout<<"a>=b"<< a>=b ;
cout<<"a<b"<< a<b ;
cout<<"a<=b"<< a<=b ;
cout<<"a==b"<< a==b ;
cout<<"a!=b"<< a!=b ;
}
SORTIE :
Saisir les valeurs a, b : 5 9
a>b : 0 //false
a<b : 1 //vrai
a>=a : 1 //vrai
a<=b : 1 //vrai
a==b : 0 //false
a!=b : 1 //vrai
3 .OPÉRATEURS LOGIQUES :
Données logiques : Une donnée est dite logique si elle véhicule l'idée de vrai ou de faux. En C++, nous utilisons le type de
données int pour représenter les données logiques. Si la valeur de la donnée est nulle, elle est considérée comme fausse. S'il
est différent de zéro (1 ou tout autre nombre entier différent de 0), il est considéré comme vrai. Le C++ dispose de trois
opérateurs logiques permettant de combiner des valeurs logiques et de créer de nouvelles valeurs logiques :

Tables de vérité pour les opérateurs AND (&&) et OR X Y X&&Y X/Y


(ID) : 0 0 0 0
1 ruth table tor NO I ( !) operator : 0 1 0 1
x 'X
0 1 1 0 0 1
1 0 1 1 I 1
Note:Le programme ci-dessous fonctionne avec les compilateurs qui supportent les normes C99.
#include<iostream.h>
#include<stdbool.h>
int main()
{
bool a,b ;
/*logique et*/
a=0;b=0 ;
cout<<" a&&b "<< a&b<<endl ;
a=0;b=1 ;
cout<<" a&&b "<< a&b<<endl ;
a=1;b=0 ;
cout<<" a&&b "<< a&b<<endl ;
a=1;b=1 ;
cout<<" a&&b "<< a&b<<endl ;
/*logique ou*/
a=0;b=0 ;
cout<" a||b "<< a||b<<endl ;
a=0;b=1 ;
cout<" a||b "<< a||b<<endl ;
a=1;b=0 ;
cout<" a||b "<< a||b<<endl ;
a=1;b=1 ;
cout<" a||b "<< a||b<<endl ;
/*non logique*/
a=0 ;
cout<" a||b "<< a||b<<endl ;
a=1 ;
cout<" a||b "<< a||b<<endl ;
retour 0 ;
}

SORTIE : 0&&0=0
0&&1=0
1&&0=0
1&&1=1
0||0=0
0||1=1
1||0=1 1||1=1 !0 =1 !1 =0

4 .OPÉRATEUR D'AFFECTATION :
L'expression d'affectation évalue l'opérande à droite de l'opérateur (=) et place sa valeur dans la variable à
gauche.
Remarque : l'opérande gauche d'une expression d'affectation doit être une variable unique.
Il existe deux formes d'affectation :
-Affectation simple
-Affectation composée

Affectation simple :
Dans les expressions algébriques, nous avons trouvé ces expressions.
Ex : a=5 ; a=a+1 ; a=b+1 ;
Ici, l'opérande de gauche doit être une variable mais pas une constante. La variable de gauche doit pouvoir
recevoir une valeur de l'expression. Si l'opérande de gauche ne peut pas recevoir de valeur et que nous lui
en attribuons une, nous obtenons une erreur de compilation.

Affectation des composés :


Une affectation composée est une notation abrégée pour une affectation simple. Elle exige que l'opérande
de gauche soit répété en tant que partie de l'expression de droite. Syntaxe : opérateur de variable+=valeur

Ex :
A+=1 ; il est équivalent à A=A+1 ;

Avantages de l'utilisation de l'opérateur d'affectation abrégé :


1. Ce qui figure à gauche n'a pas besoin d'être répété et devient donc plus facile à écrire.
2. La déclaration est plus concise et plus facile à lire.
3. La déclaration est plus efficace.

L'opérateur ++ ajoute une unité à son opérande, tandis que l'opérateur - - soustrait une unité à son opérande. Ces
opérateurs
et prennentsont
la forme suivante :
Opérateur Description
Les opérateurs d'incrémentation et de décrémentation
peuvent tous deux précéder ou suivre l'opérande. --a Pré-incrément
Incrémentation/décrémentation du postfixe :( a++/a--) a++ Post-incrément
Dans l'incrémentation postfixe (décrémentation), la valeur -a Pré-décrément
est incrémentée (décrémentée) d'une unité. Le a++ a donc a- Post-décrément
le même effet que
Certains des opérateurs d'affectation abrégés couramment utilisés sont présentés dans le tableau suivant:
Déclaration avec un simple opérateur Déclaration avec opérateur abrégé
d'affectation
a-=1
a=a+l
a=a-l a-=l
a=a*l a*=i
a=a/1 a-1
a=a% 1 a%=l
a=a*(n-l) a*=n+1
5.LES OPÉRATEURS D'INCRÉMENTATION (++) ET DE DÉCRÉMENTATION (--) :
a=a+1 ; a--a le même effet que a=a-1.
La différence entre a++ et a+1 est que si ++ se trouve après l'opérande, l'incrémentation a lieu après l'évaluation de
l'expression.
L'opérande d'une expression postfixe doit être une variable.
Ex1 :
int a=5 ;
B=a++ ; Ici la valeur de B est 5. la valeur de a est 6.
Ex2 :
int x=4 ; y=x-- ; Ici la valeur de y est 4, la valeur de x est 3
Préfixe Incrément/Décrément (++a/ --a)
Dans l'incrémentation préfixe (décrémentation), l'effet a lieu avant que l'expression qui contient l'opérateur ne soit évaluée.
C'est l'inverse de l'opération postfixe. ++a a le même effet que a=a+1.
--a a le même effet que a=a-1.
Ex : int b=4 ;
A= ++b ;
Dans ce cas, la valeur de b serait de 5 et celle de A de 5.
L'effet de l'incrémentation postfixe et préfixe est le même : la variable est incrémentée de
1. Mais ils se comportent différemment lorsqu'ils sont utilisés dans des expressions comme indiqué ci-dessus. L'exécution
de ces opérateurs est rapide par rapport à l'instruction d'affectation équivalente.

#include<iostream.h>
int main()
{
int a=1 ;
int b=5 ;
++a ;
cout<<"a="<<a<<endl ;
--b ;
cout<<"b="<<b<<endl ;
cout<<"a="<<a++<<endl ;
cout<<"a="<<a<<endl ;
cout<<"b="<<b--<<endl ;
cout<<"b="<<b<<endl ;
retour 0 ;
}
a=2
b=4
a=2
a=3
b=4
b=3
6 .OPÉRATEUR CONDITIONNEL OU OPÉRATEUR TERNAIRE :

Un opérateur ternaire nécessite deux opérandes pour fonctionner


Syntaxe :

#include<iostream.h>
void main()
{
int a, b,c ;
cout<<"Entrez les valeurs a et b :";
cin>>a>>b ;
c=a>b?a:b ;
cout<<"le plus grand de a et b est "<<c ;
}
Saisir les valeurs a et b:1
5

7 . OPÉRATEURS DE BITS : Le langage C prend en charge des opérateurs spéciaux, connus sous le nom
d'opérateurs de bits, pour la manipulation des données au niveau des bits. Elles ne s'appliquent pas aux valeurs
flottantes ou doubles.
opérateur sens

& Bitwise AND

^ Exclusif par bit OU


<< décalage vers la gauche
>> décalage vers la droite
~ complément individuel
Opérateur ET binaire (&)
L'opérateur bitwise AND est un opérateur binaire qui nécessite deux opérandes intégraux (caractère ou entier). Il effectue une
comparaison bit à bit comme indiqué ci-dessous :
Premier opérande Bit Bit du second opérande Opel & Opel
0 0 0
0 1 0
1 0 0
1 1 1

Opérateur OR binaire ( |)
L'opérateur bitwise OR est un opérateur binaire qui nécessite deux opérandes intégraux (caractère ou entier). Il
effectue une comparaison bit à bit comme indiqué ci-dessous :

Premier opérande Bit Bit du second opérande Opel | Opel


0 0 0
0 1 1
1 0 1
1 1 1

Opérateur OU EXCLUSIF binaire ( A )


L'opérateur OU EXCLUSIF binaire est un opérateur binaire qui nécessite deux opérandes intégraux (caractère
ou entier). Il effectue une comparaison bit à bit comme indiqué ci-dessous :

Premier opérande Bit Bit du second opérande Opel A Opel


0 0 0
0 1 1
1 0 1
1 1 0
Opérateurs d'équipe
Les opérateurs de décalage déplacent les bits vers la droite ou la gauche. Ils sont de deux types : . -Opérateur de décalage
vers la droite dans le sens des bits
. -Opérateur de décalage vers la gauche
Opérateur de décalage bit à bit vers la droite
Il s'agit d'un opérateur binaire qui nécessite deux opérandes intégraux. Le premier opérande est la valeur à décaler et le
second opérande spécifie le nombre de bits à décaler. Lorsque les bits sont décalés vers la droite, les bits situés à
l'extrémité droite sont supprimés et un zéro est inséré au niveau du bit MSB.
#include<iostream.h>
void main()
{
int x,shift ;
cout<<"Entrez un nombre :") ;
cin>>x ;
cout<<"enter now many times to right shift : " ;
cin>>shift ;
cout<<"Avant le décalage vers la droite :"<<x ;
x=x>>shift ;
cout<<"Après le décalage vers la droite :"<<x ;
}
Exécuter1 :
Entrez un nombre:8
entrer maintenant plusieurs fois à droite:1
Avant le passage à droite:8
Après le passage à droite:4

Explication : Le nombre saisi au clavier est 8 et le nombre binaire correspondant est 1000.
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
15 14 13 12 11 10 9 876543 21 0
Après l'exécution du programme, les données d'entrée x doivent être décalées de 2 bits vers la droite. La réponse
sous forme binaire serait la suivante :
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
15 14 13 12 11 10 9 876543 21 0

L'opérateur de décalage vers la droite divise le nombre donné par une puissance de 2. Si nous déplaçons un
nombre binaire de deux places vers la droite, nous divisons le nombre donné par 4 (2').

Opérateur de décalage bit à bit vers la gauche

Il s'agit d'un opérateur binaire qui nécessite deux opérandes intégraux. Le premier opérande est la valeur à
décaler et le second opérande spécifie le nombre de bits à décaler vers la gauche.
Lorsque les bits sont déplacés vers la gauche, les bits situés à l'extrémité gauche sont supprimés.

Ex : int a=2 ;
a"=3 ;
L'opérateur shift left est l'inverse de l'opérateur shift right. L'opérateur de décalage vers la gauche multiplie
le nombre donné par une puissance de 2. Si nous déplaçons un nombre binaire de trois places vers la
gauche, nous multiplions le nombre donné par 8 (23).
Complément à un ou Bitwise NOT

Le NOT (ou complément) par bit est une opération unaire qui effectue une négation logique sur chaque bit,
formant ainsi le complément de la valeur binaire donnée. Les chiffres qui étaient 0 deviennent I, et vice versa.
Ex : NOT 0111 (décimale 7) = 1000 (décimale 8)
En C, l'opérateur bitwise NOT est (tilde). Table de vérité :
Valeur d'expression ~ Expression
0 1
1 (non nul) 0
Remarque : l'opérateur de complément à un (Bitwise NOT) est différent de l'opérateur Logical NOT. Nous
utilisons cet opérateur dans le processus d'encodage et de décodage.
8.5 ES OPÉRATEURS SPÉCIAUX
Les opérateurs qui n'entrent dans aucune des classifications ci-dessus sont ,(virgule), sizeof, les opérateurs de
pointeurs (& et *) et les opérateurs de sélection de membres (. et ->). L'opérateur virgule est utilisé pour relier des
expressions apparentées entre elles.
La taille de l'opérateur :

Il renvoie le nombre d'octets occupés par l'opérande. L'opérande peut être une variable, une constante (valeur
de données) ou un qualificateur de type de données.
Ex : int a. c, f, d ;
c=sizeof(a) ; ici c=2, l'opérateur sizeof renvoie la taille de la variable a qui est de type int f=sizeof(long
double) ; la valeur de f est 10, ce qui correspond à la taille du qualificateur de type long double
d=sizeof(23.345) ; la valeur de d est 4, ce qui correspond à la taille de la valeur constante float

L'opérateur sizeof est normalement utilisé pour déterminer la longueur des tableaux et des structures. Il est
également utilisé pour allouer dynamiquement de l'espace à la variable s pendant l'exécution d'un programme.

L'opérateur virgule (,)

L'opérateur virgule peut être utilisé pour lier l'expression d'expressions liées est évaluée de gauche à droite et
la valeur de l'expression combinée.
Ex : a=(x=10, y=20, x+y) ;

La valeur 10 est d'abord attribuée à x, puis la valeur 20 est attribuée à y et enfin la valeur 10 est attribuée à y.
Il a la priorité la plus faible parmi tous les opérateurs.
Nous utilisons l'opérateur virgule dans les instructions de boucle et les déclarations du même type.
Opérateur Description
4- Unary plus
9.OPERATEUR UNAIRE: l'opérateur qui opère - Moins unaire
sur un seul opérande est appelé opérateur unaire. — Incrément
— Décroissance
& Adresse
— Complément
Taille des d'information
Taille de l'opérateur
Type Moulage de type

Opérateurs en c++ : Tous les opérateurs ci-dessus du langage c sont également valables en c++. Les nouveaux
opérateurs introduits en c++ sont les suivants

Sno Opérateur Symbole


1. Opérateur de résolution du champ
2. d'application
Pointeur vers un déclarateur de ::*
3. membre
Pointeur vers l'opérateur membre ->*,->
4. Pointeur vers l'opérateur membre .*
5. nouveau Opérateur d'allocation de mémoire
6. supprimer Opérateur de libération de mémoire
7. endl Opérateur de ligne
8. setw Opérateur de largeur de champ
9. insertion <<
10. Extraction >>

8.6 opérateur de résolution de conflits :


Champ d'application:-La visibilitéou la disponibilité d'une variable dans un programme est appelée champ
d'application. Il existe deux types de champ d'application : i) le champ d'application local et ii) le champ
d'application global.
Portée locale : la visibilité d'une variable est locale à la fonction dans laquelle elle est déclarée.
Portée globale : visibilité d'une variable pour toutes les fonctions de
un opérateur de résolution de portée de programme dans ": :" .
Elle est utilisée pour accéder aux variables globales si les mêmes variables sont déclarées comme locales.
et global PROGRAM1.2:-
#include<iostream.h>
int a=5 ;
void main()
{
int a=10 ;
cout<"Local a="<<a<<endl ;
cout<"Global a="<<::a<<endl ;
}
Résultat attendu :
Local a=10
Global a=5
Membre Opérateur de déréférencement:-
1. Pointeur vers un déclarateur de ::*
membre vers l'opérateur membre
2. Pointeur ->*,->
3. Pointeur vers l'opérateur membre .*
Pointeur vers un déclarateur de membre ::*
Cet opérateur est utilisé pour déclarer un pointeur sur un membre de la classe #include<iostream.h>
échantillon de classe
{public :
int x ;
};
int main()
{ échantillons ; //objet
int sample ::*p;//déclinaison du pointeur s.*p=10 ; //correct
cout<<s.*p ;
} Sortie:10
2. pointeur sur l'opérateur membre ->*
#include<iostream.h> classe sample
{
public :
int x ;
void display()
{
cout<"x="<<x<<endl ;
}
};
int main()
{
échantillons ; //objet
échantillon *ptr ;
int sample::*f=&sample::x ;
s.x=10 ;
ptr=&s ;
cout<<ptr->*f ;
ptr->display() ;
}

3. Pointeur vers l'opérateur membre


.*
#include<iostream.h>
échantillon de classe
{
public : int x ;
};
int main()
{
échantillons ; //objet
int sample ::*p;//déclinaison du pointeur
s.*p=10 ; //correct
cout<<s.*p ;
}

Manipulateurs :
Les manipulateurs sont les opérateurs utilisés pour formater les données à afficher à l'écran. Les
manipulateurs les plus couramment utilisés sont endl et setw.
endl:- il est utilisé dans l'instruction de sortie et insère un saut de ligne. Il est similaire au caractère de
nouvelle ligne ("\n")
ex : cout<<"a=2"<<endl ;
cout<"name=sunil"<<endl ;
Sortie :
a=2
name=sunil
setw:-
ce manipulateur permet de spécifier la largeur d'un champ à imprimer à l'écran
Cette fonction est disponible dans le fichier d'en-tête iomanip.h.

#include<iostream.h>
#include<iomanip.h>
using namespace std ;
int main()
{
int s=123 ;
cout<<"s="<<setw(10)<<s ;
}
sortie
s= 123
Opérateurs d'insertion (<<) et d'extraction (>>) :
les opérateurs sont utilisés avec des objets de sortie et d'entrée
ex :
cout<<"Enter n" ;
cin>>n

Instructions de contrôle:- Leflux d'exécution des instructions dans un programme est appelé contrôle.
L'instruction de contrôle est une instruction qui contrôle le flux d'exécution du programme. Les déclarations de
contrôle sont classées dans les catégories suivantes.
1. déclarations de contrôle séquentiel
2. les instructions de contrôle conditionnel
(type) expression ;
3. déclarations de contrôle inconditionnelles Ou
1. séquentiel contrôle déclarations:- type (expression) ; Instructions de contrôle
déclarations assure que les séquentiel (ou
) sont exécutés dans le même l'ordre dans lequel
ils apparaissent dans le programme, c'est-à- par défaut système
dire par les instructions dans l'ordre du
exécute en séquentiel
programme.
2. les instructions de contrôle conditionnel :les instructions qui sont exécutées lorsqu'une condition est vraie.
Ces déclarations sont divisées en trois catégories, à savoir
1. déclarations de prise de décision
2. changer la déclaration de contrôle de cas ou
3. les instructions de contrôle en boucle ou les répétitions
1 Déclarations de prise de décision:- Ces déclarations sont utilisées pour contrôler le flux d'exécution d'un
programme en prenant une décision en fonction d'une condition, d'où leur nom de déclarations de prise de
décision.
Les déclarations de prise de décision sont de quatre types
1.simple si
2.si autre
3.imbriqué si autre
4.1 f else ladder

1.51 Exemple d'instruction if : si l'expression du test est vraie, l'instruction if exécute les instructions qui
suivent immédiatement l'instruction if.
Syntaxe :
Si(expression du test)

Liste des déclarations ;

/*le plus grand des deux nombres*/


#include<stdio.h>
int main()
{
int a,b ;
cout<<"Entrez deux entiers quelconques :";
cin>>a>>b ;
si(a>b)
cout<<"A est plus grand que B\n A="<<a ;
si(b>a)
cout<<"B est plus grand que A\n A="<<b ;
retour 0 ;
}
2 . déclaration if -else :
Si l'expression du test est vraie, le bloc d'instructions suivant if est exécuté et si l'expression du test est
fausse, les instructions du bloc else sont exécutées if (expression du test)
{
bloc de déclaration1 ;
}
autre
{
bloc de déclaration2 ;
}

/*le plus grand des deux nombres*/

#include<iostream.h>
int main()
{
int a,b ;
cout<<"Entrez deux entiers quelconques :";
cin>>a>>b ;
if(a>b) cout<<"A est plus grand que B\n A="<<a ;

cout<<"B est plus grand que A\n A="<<b ;


autr
e retour 0 ;

3 Emboîtement des instructions if-else IL ESTégalement possible d'emboîter une instruction if à l'intérieur d'une autre.
LORSQU'une série de décisions doit être prise.
Instruction If -else placée à l'intérieur d'une autre instruction if else Syntaxe :
If( test expression) {If(test expression)
{ //statements } else { //énoncés } }
else
{If(test expression) { //énoncés } else {
//états }
} /*le plus grand des trois nombres*/
#include<iostream.h>
#include<conio.h> int main() { int
a,b,c ;
cout<<"Entrez les valeurs a,b,c :";
cin>>a>>b>>c ;
if(a>b) {
if(a>c) {
cout<<"A est
le plus grand
des trois
nombres" ;
cout
"A="<<a ;
} else {
cout<<"C est
le plus grand des trois nombres" ; cout<<"c="<<c ;
} } else {if(b>c) {
cout<<"B est le plus grand des trois nombres" ; cout<<"B="<<b ;
}
autre
{
cout<<"C'est le plus grand des trois nombres" ;
cout<<"c="<<c ;
}
}
getch() ;
retour 0 ;
}
4.1 f else ladder

if(condition1)
déclaration1 ;
else if(condition2)
déclaration 2 ;
else if(condition3)
déclaration n ;
autre
déclaration par défaut.
statement-x ;

L'imbrication des if-else dépend des conditions à traiter.

La condition est évaluée de haut en bas. Si une condition est vraie, l'instruction qui lui est associée est exécutée.
Lorsque toutes les conditions sont fausses, la partie finale else contenant des instructions par défaut est exécutée.

#include<iostream.h>
void main()
{
int per ;
cout<<"Enter
pourcentage" ; cin>>per ;
si(per>=80)
cout<<"Sécurisé
Distinction"<<endl ; else if(per>=60)
cout<<"Secured First
Division"<<endl ; else if(per>=50)
cout<<"Sécurisé
Deuxième division"<<endl ;
else if(per>=40)
cout<<"Sécurisé
Division"<<endl ; Troisi
autre èmem
cout<<"Fail"<<endl

L'ÉNONCÉ DE L'INTERRUPTEUR ou la SÉLECTION MULTIDIRECTIONNELLE:


Outre la sélection à deux voies, la plupart des langages de programmation proposent un autre concept de sélection, connu
sous le nom de sélection à plusieurs voies. La sélection multidirectionnelle permet de choisir entre plusieurs alternatives. C
dispose de deux moyens différents pour mettre en œuvre la sélection multidirectionnelle : l'instruction switch et la
construction else-if.
Si, par exemple, nous avons le choix entre plusieurs options valables, nous pouvons utiliser l'instruction
switch à la place de l'instruction if.
switch(expression)
{.
cas valeur-1 :
bloc-1
pause ;
valeur de cas-2 :
bloc-2
pause ;

par défaut :
bloc par défaut ;

/*programme de simulation d'une simple calculatrice */ #include<iostream.h>


int main()
{
float a,b ;
char opr ;

cout<<"Enter number1 operator number2 : " ;


cin>>a>>oper>>b ;
switch(opr)
{
cas '+' :
cout<<"Somme : "<<(a + b)<<endl ;
pause ;
case '-' : cout<<"Différence : "<<(a -b)<<endl ;
pause ;
case '*' : cout<<"Produit : "<<a * b<<endl ;
pause ;
case '/' : cout<<"Quotient :"<<(a / b)<<endl ;
pause ;
défaut : cout<<"Opération non valide !"<<endl ;
}
retour 0 ;
}

Les instructions de contrôle en boucle ou les répétitions :


Un bloc ou un groupe d'instructions exécuté de manière répétée jusqu'à ce qu'une certaine condition soit
remplie est appelé boucle. Le groupe d'instructions entourées d'accolades est appelé bloc ou instruction
composée.
Nous disposons de deux types de structures de bouclage.
Un contrôle dans lequel la condition est testée avant d'entrer dans le bloc d'instructions est appelé contrôle
d'entrée.
L'autre boucle dans laquelle la condition est vérifiée à la sortie est appelée boucle contrôlée de sortie.
Les déclarations de boucles peuvent être divisées en trois catégories, comme indiqué ci-dessous
1 .déclaration de boucle while
2 .do while déclaration en boucle
3 .déclaration de boucle for

1 .DÉCLARATION WHILE :

While(test condition)
{
corps de la boucle
}
Il s'agit d'une boucle d'entrée contrôlée. La condition est évaluée et
si elle est vraie, le corps de la boucle est exécuté. Après l'exécution du
corps, la condition est à nouveau évaluée et si elle est vraie, le corps est à
nouveau exécuté. Cette opération se poursuit jusqu'à ce que la condition de
test devienne fausse.

programme c pour trouver la somme de n nombres naturels */


#include<iostream.h>
int main()
{
int i = 1,sum = 0,n ;
cout<<"Enter N"<<end ;
cin>>n ;
while(i<=n)
{
somme = somme + i ;
i=i+1;
}

cout<<"La somme des premiers"<<n<"entiers naturels est :"<<sum<<endl ; return 0 ;


}
2 .DO WHILE DÉCLARATION :

tlo-while - ( Sortie contrôlée )


La boucle while ne permet pas d'exécuter le corps si la condition de test est fausse. Le do while est une
boucle à sortie contrôlée et son corps est exécuté au moins une fois.

faire
{
corps
}while(test condition) ;

/*c programme pour trouver la somme de n nombres naturels */


#include<stdio.h>
int main()
{
int i = 1,sum = 0,n ;
cout<<"Enter N"<<endl ;
cin>>n

faire{
somme = somme + i ;
i=i+1;
} while(i<=n) ;
cout<<"Somme des premiers"<< n<<" nombres naturels
est :"<<sum ; retour 0 ;
}
Remarque : si la condition de test est fausse avant l'exécution de la boucle, la boucle While s'exécute zéro fois, alors que la
boucle do--while s'exécute une fois .

3.FOR LOOP : Il s'agit également d'une boucle de contrôle d'entrée qui fournit une
structure plus concise
Syntaxe :
for(initialisation ; expression de test ; incrémentation/décrémentation) {
déclarations ;
}
La déclaration est divisée en trois expressions, chacune étant
séparée par un point-virgule ;
1.l'expression d'initialisation est utilisée pour initialiser les
variables
2. l'expression de test est responsable de la poursuite de la
boucle. Si l'expression de test est fausse, la boucle se termine
3.l'expression d'incrémentation/décrémentation consiste en
un opérateur d'incrémentation ou de décrémentation Ce
processus se poursuit jusqu'à ce que la condition de test soit
satisfaite.

/*c programme pour trouver la somme de n nombres naturels */


#include<stdio.h>
int main()
{
int i ,sum = 0,n ;
cout<<"Enter N" ;
cin>>n ;

for(i=1;i<=n;i++)
{
somme = somme + i ;
}

cout<<"La somme des premiers"<<n<" nombres naturels est:%d"<<sum ; return 0 ;

Boucles imbriquées:L'écriture d'une instruction de contrôle de boucle à l'intérieur d'une autre instruction
de contrôle de boucle est appelée instruction de boucle imbriquée.
Ex :
for(i=1;i<=10;i++)
for(j=1;j<=10;j++) cout<<i<<j ;

/*programme pour imprimer les nombres premiers jusqu'à un nombre donné*/


#include<stdio.h>
#include<conio.h>
void main()
{
int n,i,fact,j ;
clrscr() ;
cout<<"enter the number :";
cin>>n
for(i=1;i<=n;i++)
{fact=0 ;
//CETTE BOUCLE VÉRIFIERA QU'UN NON EST BIEN UN PREMIER NON. OU
NOT. for(j=1;j<=i;j++)
{
si(i%j==0) fait++ ;
}
si(fait==2)

cout<i<<"\t" ;
}
getch( ) ;
}
Sortie :
Entrez le nombre : 5
2 35

Déclarations de contrôle inconditionnelles :


Déclarations qui transfèrent le contrôle d'une partie du programme à une autre.
sans condition Différentes déclarations sans condition sont
1)goto
2) rupture
3)continuer
1.goto :- L'instruction goto est utilisée pour le branchement inconditionnel ou le transfert de
l'exécution du programme à l'instruction étiquetée.
L'instruction goto permet de passer sans condition d'un point à un autre du programme. Le goto nécessite une
étiquette afin d'identifier le lieu où la branche doit être fabriquée. Une étiquette est un nom de variable valide
qui doit être suivi de deux points ( ;). L'étiquette est placée immédiatement
avant la déclaration où le contrôle doit être transféré. La forme générale de goto est la suivante
ci-dessous :
Geto étiquette :
label ; déclaration ;

étiquette :
déclaratio Geto
n; label ;
Saut avant Saut en arrière
L'étiquette : peut se trouver n'importe où dans le programme, avant ou après l'instruction goto label ;.

Si l'étiquette : est placée après l'étiquette goto ;, certaines instructions seront ignorées et le saut est connu sous
le nom de saut en avant.

Si l'étiquette : est placée avant l'étiquette goto, une boucle sera formée et certaines instructions seront
exécutées de manière répétée. Un tel saut est connu sous le nom de saut en arrière.

/*c programme pour trouver la somme de n nombres naturels */


#include<stdio.h>
int main()
{
int i ,sum = 0,n ;
cout<<"Enter N" ;
cin>>n ;
i=1 ;
L1 :
somme = somme + i ;
i++ ;
if(i<=n) goto L1 ;

cout<<"La somme des premiers "<<n<" nombres naturels est"<<sum ; return 0 ;


break:-lorsqu'une instruction break est rencontrée à l'intérieur d'une boucle, la boucle
est immédiatement quittée et le programme continue avec les instructions qui suivent
immédiatement la boucle.
/*c programme pour trouver la somme de n nombres naturels */
#include<stdio.h>
int main()
{
int i ,sum = 0,n ;
cout<<"Enter N" ;
cin>>n ;
i=1 ;
L1 :
somme = somme + i ;
i++ ;
if(i>n) break ;
aller à L1 ;

cout<<"La somme des premiers"<<n<<"nombres naturels est : "<<sum ; return 0 ;


}

Continue:Elle est utilisée pour poursuivre l'itération de l'instruction de la boucle en sautant les
instructions après l'instruction continue. Il permet au contrôle de passer directement à la
condition de test et de poursuivre la boucle.
/*c programme pour trouver la somme de n nombres positifs lus au clavier*/
#include<stdio.h>
int main()
{
int i ,sum = 0,n,number ;
cout<<Enter N" ;
cin>>n ;
for(i=1;i<=n;i++)
{
cout<<"Entrez un nombre :";
cin>>numéro ;
si(nombre<0) continuer ;
somme = somme + nombre ;
}
cout<<"La somme de"<<n<<" nombres est :"<<sum ;
retour 0 ;
}
UNITÉ -2

Fonctions, classes et objets :


Introduction des classes, définition des classes, définition des membres, objets, contrôle d'accès,
Portée de la classe, Opérateur de résolution de portée, Fonctions en ligne, Allocation de mémoire pour les
objets, Membres statiques des données, Fonctions statiques des membres, Tableaux d'objets, Objets en tant
qu'arguments de fonction, Fonctions amies.

Introduction de la classe :
Une approche de programmation orientée objet est une collection d'objets et chaque objet est constitué
de structures de données et de procédures correspondantes. Le programme est réutilisable et plus facile à
maintenir.
L'aspect important d'OOP est une classe dont la syntaxe est similaire à celle de la structure.

classe: Il s'agit d'une collection de données et de fonctions membres qui manipulent les données. Les
composants de données de la classe sont appelés membres de données et les fonctions qui manipulent les
données sont appelées fonctions membres.
Il peut également être appelé "blue print" ou "prototype" et définit les variables et les fonctions
communes à tous les objets d'un certain type. Elle est également connue sous le nom de type de données défini
par l'utilisateur ou ADT (type de données abstraites).

Syntaxe:-

classe nom_de_la_classe {

Spécification d'accès :
Déclarations de variables ;

Spécification d'accès :
les déclarations de fonctions ;

};

Contrôle d'accès :
Les spécificateurs d'accès ou modificateurs d'accès sont les étiquettes qui spécifient le type d'accès
accordé aux membres d'une classe. Ils sont utilisés pour masquer les données. Ces modes sont également
appelés modes de visibilité. Il existe trois types de spécificateurs d'accès
1.privé
2.public
3.protégé

1.Privé :
Si les membres des données sont déclarés comme étant d'accès privé, ils ne peuvent pas être accédés par
d'autres fonctions en dehors de la classe. Elle n'est accessible que par les fonctions déclarées dans la classe. Elle
est déclarée par le mot clé "private".

2.public :
Si les membres des données sont déclarés d'accès public, ils peuvent être accédés par d'autres fonctions
en dehors de la classe. Il est déclaré par le mot clé "public".

3.protégé : Le niveau d'accès de la déclaration protégée se situe entre public et privé. Ce spécificateur d'accès
est utilisé au moment de l'héritage
Note:-
Si aucun spécificateur d'accès n'est spécifié, il est traité par défaut comme étant privé.
Le spécificateur d'accès par défaut d'une structure est public alors que celui d'une classe est "privé"

Exemple :
classe étudiant
{
private : int roll ;
char name[30] ;
public :
void get_data()
{
cout<<"Enter roll number and name" : cin>>roll>>name ;
}
void put_data()
{

cout<"Numéro du rôle :"<<roll<<endl ;


cout<<"Nom :"<<nom<<endl ;
}
};
Objet:- L'instance d'une classe est appelée objet.
Syntaxe :
nom_de_la_classe nom_de_l'objet ;
Ex :
étudiants ;
Accès aux membres : l'opérateur -dot est utilisé pour accéder aux membres de la classe

Nom d'objet.nom de fonction(arguments réels) ;

Ex :
s.get_data() ;
s.put_data() ;
Remarque :
1 Si le spécificateur d'accès n'est pas spécifié dans la classe, le spécificateur d'accès par défaut est
privé.
2 Toutes les fonctions membres doivent être déclarées publiques, sinon elles ne sont pas accessibles en
dehors de la classe. Objet :
L'instance d'une classe est appelée objet.
Syntaxe :
Nom de l'objet Class_name ;

Exemple :
étudiants ;
dans l'exemple ci-dessus, s est l'objet. Il s'agit d'une entité en temps réel qui peut être utilisée
Écrire un programme pour lire les données d'un élève
#include<iostream>
using namespace std ;
classe étudiant
{
privé :
rouleau int ;
char name[20] ;

public :
void getdata()
{cout<<"Enter Roll number :";
cin>>roll ;
cout<<"Enter Name :";
cin>>nom ;
}
void putdata()
{cout<<"Roll no :"<<roll<<endl ;
cout<<Nom :"<<nom<<endl ;
}
};
int main()
{
étudiants ;
s.getdata() ;
s.putdata() ;
retour 0 ;
}
Champ d'application Opérateur de résolution :
Champ d'application:-La visibilitéou la disponibilité d'une variable dans un programme est
appelée champ d'application. Il existe deux types de champ d'application : i) le champ
d'application local et ii) le champ d'application global.
Portée locale : la visibilité d'une variable est locale à la fonction dans laquelle elle est
déclarée.
Portée globale : visibilité d'une variable pour toutes les fonctions d'un programme.
Opérateur de résolution de portée dans ": :" .
Elle est utilisée pour accéder aux variables globales si les mêmes variables sont déclarées
comme locales et globales.

#include<iostream.h>
int a=5 ;
void main()
{
int a=1 ;
cout<"Local a="<<a<<endl ;
cout<"Global a="<<::a<<endl ;
}

Champ d'application de la classe :


L'opérateur de résolution de portée(: :) est utilisé pour définir une fonction en dehors d'une classe.

#include <iostream>
using namespace std ;
échantillon de classe
{
public :
void output() ; //déclaration de fonction
};
// définition de la fonction en dehors de la
class void sample::output() {
cout << "Fonction définie en dehors de la classe.\n" ;

};
int main() {
échantillon obj ;
obj.output() ;
retour 0 ;
}
Sortie du programme :
Fonction définie en dehors de la classe.

Écrire un programme pour trouver l'aire d'un rectangle


#include<iostream.h>
classe rectangle
{
int L,B ;
public :
void get_data() ;
void area() ;
};

void rectangle::get_data()
{
cout<<"Enter Length of rectangle" ;
cin>>L ;
cout<<"Entrez la largeur du rectangle" ;
cin>>B ;
}
int rectangle::area()
{
retour L*B ;
}
int main()
{
rectangle r ;
r.get_data() ;
cout<<"La surface du rectangle est"<<r.area() ;
retour 0 ;
}

LES FONCTIONS EN LIGNE :


Définition :
Une fonction en ligne est une fonction qui est développée en ligne lorsqu'elle est invoquée. L'expansion
en ligne accélère l'exécution d'un programme parce qu'elle élimine la surcharge liée à l'appel et au retour
d'une fonction. Elle est définie par l'utilisation du mot clé " inline" (en ligne)

Nécessité d'une fonction en ligne :


> L'un des objectifs de l'utilisation de fonctions dans un programme est d'économiser de l'espace mémoire, ce qui devient
appréciable lorsqu'une fonction est susceptible d'être appelée de nombreuses fois.
Chaque fois qu'une fonction est appelée, elle prend beaucoup de temps supplémentaire pour exécuter une série
d'instructions pour des tâches telles que le saut dans la fonction, l'enregistrement des registres, l'insertion des
arguments dans la pile et le retour à la fonction appelante.
>
Lorsqu'une fonction est petite, un pourcentage substantiel du temps d'exécution peut être consacré à ces frais
généraux.
Une solution à ce problème consiste à utiliser des définitions de macro, appelées macros. Les macros du
préprocesseur sont très répandues en C. Le principal inconvénient des macros est qu'elles ne sont pas de
véritables fonctions et que, par conséquent, le contrôle d'erreur habituel ne se produit pas lors de la compilation.
Le C++ propose une solution différente à ce problème. Pour éliminer le coût des appels à de petites
fonctions, le C++ propose une nouvelle fonctionnalité appelée fonction en ligne.
Formulaire général :
inline function-header (en-tête de fonction en ligne)
{
le corps de la fonction ;
Eg :
#include<iostream.h>
inline float mul(float x, float y)
{
retour (x*y) ;
}
inline double div(double p, double q)
{
retour (p/q) ;
}
int main()
{
float a=12.345 ;
float b=9,82 ;
cout<<mul(a,b) ;
cout<<div(a,b) ;
retour 0 ;
}
Propriétés des fonctions en ligne :
1. la fonction Inline envoie une requête mais pas une commande au compilateur
2. le compilateur peut servir ou ignorer la demande
3. si la fonction a trop de lignes de code ou si elle a une logique compliquée, elle est exécutée comme
une fonction normale.
Situations dans lesquelles l'affichage en ligne ne fonctionne pas :
>
Une fonction qui renvoie une valeur, si elle contient une boucle de commutation ou les deux, elle est traitée comme une
fonction normale.
>
Si une fonction ne renvoie aucune valeur et qu'elle contient une instruction de retour, elle est traitée comme une fonction
normale.
>
Si la fonction contient des variables statiques, elle est exécutée comme une fonction normale.
>
Si la fonction en ligne est déclarée comme une fonction récursive, elle est exécutée comme une
fonction normale.
Allocation de mémoire pour les objets : La mémoire des objets est allouée lorsqu'ils sont déclarés, mais pas
lorsque la classe est définie. Tous les objets d'une classe donnée utilisent les mêmes fonctions membres. Les
fonctions membres sont créées et placées en mémoire une seule fois lorsqu'elles sont définies dans la définition
de la classe.
MEMBRES STATIQUES DE LA CLASSE

Membres des données statiques


Fonctions statiques
Membres statiques des données :
Un membre de données d'une classe peut être qualifié de statique. Une variable membre statique présente
certaines caractéristiques particulières :
Il est initialisé à zéro lorsque le premier objet de sa classe est créé. Aucune autre initialisation n'est
autorisée.
Une seule copie de ce membre est créée pour l'ensemble de la classe et est partagée par tous les objets de cette classe,
quel que soit le nombre d'objets créés.
Il n'est visible qu'à l'intérieur de la classe, mais sa durée de vie est celle du programme tout entier.
Les membres statiques sont définis par le mot-clé "static

Syntaxe :
Nom de la classe de type de données::static_variable Nom ;
Ex : int item::count ;
#include<iostream.h>
#include<conio.h>
élément de classe
{
statique int count ;
nombre int ;
public :
void getdata(int a) {
nombre=a ; compte++ ;
}
void getcount()
{
cout<<"count is"<<count ;
}
};
int item::count;//decleration
int main()
{
points a, b, c ;
a.getcount() ;
b.getcount() ;
c.getcount() ;
a.getdata(100) ;
b.getdata(200) ;
c.getdata(300) ;
cout<<"Après lecture des données" ;
a.getcount() ;
b.getcount() ;
c.getcount() ;
retour 0 ;
}
Sortie :
le compte est à 0
le compte est à 0
le compte est à 0
Après la lecture des données
le compte est de 3
le compte est de 3
le compte est de 3
Fonctions statiques
Tout comme les variables membres statiques, nous pouvons également avoir des fonctions membres
statiques. Une fonction membre déclarée statique possède les propriétés suivantes :
Une fonction statique ne peut avoir accès qu'à d'autres membres statiques (fonctions ou variables)
déclarés dans la même classe.
Une fonction membre statique doit être appelée en utilisant le nom de la classe (au lieu de ses objets)
comme suit : nom-de-la-classe : : nom-de-la-fonction;

#include<iostream.h>
test de classe
{
code int ;
statique int count ;
public :
void setcode()
{
code=++count ;
}
void showcode()
{
cout<<"numéro d'objet"<<code ;
}
static void showcount()
{
cout<<"count"<<count ;
}
};
int test::count ;
int main()
{
test t1,t2 ;
t1.setcode() ;
t2.setcode() ;
test::showcount() ;
test t3 ;
t3.setcode() ;
test::showcount() ;
t1.showcode() ;
t2.showcode() ;
t3.showcode() ;
retour 0 ;
}
Sortie :
compte 2
compte 3
objet numéro 1
objet numéro 2
objet numéro 3

Tableaux d'objets : Les tableaux de variables de type "classe" sont appelés "tableaux d'objets". Un tableau
d'objets est stocké dans la mémoire de la même manière qu'un tableau ordinaire.
Syntaxe :
classe nom_de_la_classe
{

privé :
membres du type de données ;
public :
les membres de type de données ; les fonctions des membres ;
};

Tableau d'objets :
Nom de la classe nom de l'objet [taille] ;
Où taille est la taille du tableau
Ex :
Ma classe obj[10] ;
Écrire un programme pour initialiser un tableau d'objets et les imprimer.
#include<iostream>
using namespace std ;
classe MyClass
{
int a ;
public :
void set(int x)
{
a=x ;
}

int get()
{
retourner a ;
}
};
int main()
{
MyClass obj[5] ;
for(int i=0;i<5;i++)
obj[i].set(i) ;
for(int i=0;i<5;i++)
cout<"obj["<<i<<"].get() :"<<obj[i].get()<<endl ;
}
Sortie :
obj[0].get():0
obj[1].get():1
obj[2].get():2
obj[3].get():3
obj[4].get():4

Les objets en tant qu'arguments de fonction : Les objets peuvent être utilisés comme arguments pour
fonctions Cela peut se faire de trois manières
a. Pass-by-value ou call by value
b. Pass-by-address ou call by address
c. Passage par référence ou appel par référence

a.Pass-by-value - Une copie de l'objet (objet réel) est envoyée à la fonction et affectée à l'objet de la fonction
appelée (objet formel). Les copies réelles et formelles des objets sont stockées à différents endroits de la
mémoire. Par conséquent, les modifications apportées à l'objet formel ne sont pas répercutées sur l'objet réel.
écrire un programme pour échanger les valeurs de deux objets
écrire un programme pour échanger les valeurs de deux objets
#include<iostream.h>
using namespace std ;
classe sample2 ;
classe sample1
{
int a ;
public :
void getdata(int x) ;
friend void display(sample1 x,sample2 y) ;
friend void swap(sample1 x,sample2 y) ;
};
void sample1::getdata(int x)
{
a=x ;
}
classe sample2
{
int b ;
public :
void getdata(int x) ;
friend void display(sample1 x,sample2 y) ;

friend void swap(sample1 x,sample2 y) ;


};
void sample2::getdata(int x)
{
b=x ;
}
void display(sample1 x,sample2 y)
{
cout<<"Les données de l'objet 1 sont"<<endl ;
cout<<"a="<<x.a<<endl ;
cout<<"Les données de l'objet 2 sont"<<endl ;
cout<"b="<<y.b<<endl ;
}
void swap(sample1 x,sample2 y)
{
int t ;
t=x.a ;
x.a=y.b ;
y.b=t ;
}
int main()
{
échantillon1 obj1 ;
échantillon2 obj2 ;
obj1.getdata(5) ;
obj2.getdata(15) ;
cout<<"Avant l'échange de données entre deux objets
" ; display(obj1,obj2) ;
swap(obj1,obj2) ;
cout<<"après l'échange de données entre deux objets" ;
afficher(obj1,obj2) ;
}
Avant l'échange de données entre deux objets
Les données de l'objet 1 sont a=5
Les données de l'objet 2 sont b=15
après l'échange de données entre deux objets
Les données de l'objet 1 sont a=5
Les données de l'objet 2 sont b=15
b. Passage par l'adresse : L'adresse de l'objet est envoyée comme argument à la fonction.
Ici, l'esperluette (&) est utilisée comme opérateur d'adresse et la flèche (->) comme opérateur de référencement.
Si une modification est apportée aux arguments formels, alors il y a une modification des arguments réels
écrire un programme pour échanger les valeurs de deux objets
#include<iostream.h>
using namespace std ;
classe sample2 ;
classe sample1
{
int a ;
public :
void getdata(int x) ;
friend void display(sample1 x,sample2 y) ;
friend void swap(sample1 *x,sample2 *y) ;

};
void sample1::getdata(int x)
{
a=x ;
}
classe sample2
{
int b ;
public :
void getdata(int x) ;
friend void display(sample1 x,sample2 y) ;
friend void swap(sample1 *x,sample2 *y) ;
};
void sample2::getdata(int x)
{
b=x ;
}
void display(sample1 x,sample2 y)
{
cout<<"Les données de l'objet 1 sont"<<endl ;
cout<<"a="<<x.a<<endl ;
cout<<"Les données de l'objet 2 sont"<<endl ;
cout<"b="<<y.b<<endl ;
}
void swap(sample1 *x,sample2 *y)
{
int t ;
t=x->a ;
x->a=y->b ;
y->b=t ;
}
int main()
{
échantillon1 obj1 ;
échantillon2 obj2 ;
obj1.getdata(5) ;
obj2.getdata(15) ;
cout<<"Avant l'échange de données entre deux objets" ;
afficher(obj1,obj2) ;
swap(&obj1,&obj2) ;
cout<<"après l'échange de données entre deux objets" ;
afficher(obj1,obj2) ;
}
Avant l'échange de données entre deux objets
Les données de l'objet 1 sont a=5
Les données de l'objet 2 sont b=15
après l'échange de données entre deux objets
Les données de l'objet 1 sont a=15
Les données de l'objet 2 sont b=5 c.Pass-by-reference:Une référence d'objet est envoyée comme argument à la
fonction.
La référence à une variable fournit un nom alternatif pour une variable précédemment définie. Si une
modification est apportée à la variable de référence, la variable d'origine est modifiée.
Une variable de référence peut être déclarée comme suit

Variable de type de données et de référence =variable ;

int x=5 ;
int &y=x ;

Ex :
Ecrire un programme pour trouver la somme de n nombres naturels en utilisant la variable de référence
#include<iostream.h>.
using namespace std ;
int main()
{
int i=0 ;
int &j=i ;
int s=0 ;
int n ;
cout<<"Enter n :";
cin>>n ;
while(j<=n)
{
s=s+i ;
i++ ;
}
cout<<"sum="<<s<<endl ;
}
Sortie :
Entrer n:10
somme=55
écrire un programme pour échanger les valeurs de deux objets
#include<iostream.h>
using namespace std ;
classe sample2 ;
classe sample1
{
int a ;
public :
void getdata(int x) ;
friend void display(sample1 x,sample2 y) ;
friend void swap(sample1 &x,sample2 &y) ;
};
void sample1::getdata(int x)
{
a=x ;
}
classe sample2
{
int b ;
public :
void getdata(int x) ;
friend void display(sample1 x,sample2 y) ;
friend void swap(sample1 &x,sample2 &y) ;
};
void sample2::getdata(int x)
{
b=x ;
}
void display(sample1 x,sample2 y)
{
cout<<"Les données de l'objet 1 sont"<<endl ;
cout<<"a="<<x.a<<endl ;
cout<<"Les données de l'objet 2 sont"<<endl ;
cout<"b="<<y.b<<endl ;
}
void swap(sample1 &x,sample2 &y)
{
int t ;
t=x.a ;
x.a=y.b ;
y.b=t ;
}
int main()
{
échantillon1 obj1 ;
échantillon2 obj2 ;
obj1.getdata(5) ;
obj2.getdata(15) ;
cout<<"Avant l'échange de données entre deux objets" ;
afficher(obj1,obj2) ;
swap(obj1,obj2) ;
cout<<"après l'échange de données entre deux objets" ;
afficher(obj1,obj2) ;
}
Sortie :
Avant l'échange de données entre deux objets
Les données de l'objet 1 sont a=5
Les données de l'objet 2 sont b=15
après l'échange de données entre deux objets
Les données de l'objet 1 sont a=15
Les données de l'objet 2 sont b=5
FONCTIONS AMIES :Les membres privés ne sont pas accessibles depuis l'extérieur de la classe, c'est-à-
dire que .... une fonction non membre ne peut pas avoir accès aux données privées d'une classe. En C++, une
fonction non membre peut accéder à la fonction privée en rendant la fonction conviviale pour une classe.
Définition :
Une fonction amie est une fonction déclarée dans une classe et définie en dehors de cette classe. Il ne
nécessite pas d'opérateur de résolution de champ d'application pour définir . Il peut accéder aux membres privés
d'une classe. Il est déclaré en utilisant le mot-clé "friend"
Ex :
échantillon de classe
{ int x,y ; public : sample(int a,int b) ;
ami int sum(sample s) ;
};
sample::sample(int a,int b)
{ x=a;y=b ;
}
int sum(samples s)
{ int sum ;
sum=s.x+s.y ;
retour 0 ;
}
void main()
{
Exemple obj(2,3) ;
int res=sum(obj) ;
cout<< "sum="<<res<<endl ;
}
Une fonction d'ami possède certaines caractéristiques particulières :
Il n'est pas dans la portée de la classe à laquelle il a été déclaré comme ami.
Comme il n'est pas dans la portée de la classe, il ne peut pas être appelé en utilisant l'objet de cette classe. Elle peut être
invoquée comme une fonction normale sans l'aide d'aucun objet.
Contrairement aux fonctions membres, elle ne peut pas accéder directement aux noms des membres et doit utiliser un nom
d'objet et un opérateur d'appartenance au point pour chaque nom de membre.
Il peut être déclaré dans la partie publique ou privée d'une classe sans que cela n'affecte sa signification.
En général, il a les objets comme arguments.
#include<iostream.h> classe sample
{
int a ;
int b ;
public :
void setvalue()
{
a=25 ;
b=40 ;
}
ami float mean(sample s) ;
};
float mean(sample s)
{
return float(s.a+s.b)/2.0 ;
}
int main()
{
l'échantillon X ;
X.setvalue() ;
cout<<"Mean value="<<mean(X) ;
retour 0 ;
}
écrire un programme pour trouver le maximum de deux nombres en utilisant la fonction friend pour
deux classes différentes #include<iostream>.
using namespace std ;
classe sample2 ;
classe sample1
{
int x ;
public :
sample1(int a) ;
friend void max(sample1 s1,sample2 s2)
};
sample1::sample1(int a)
{
x=a ;
}
classe sample2
{
int y ;
public :
sample2(int b) ;
friend void max(sample1 s1,sample2 s2)
};
Sample2::sample2(int b)
{
y=b ;
}
void max(sample1 s1,sample2 s2)
{
Si(s1.x>s2.y)
cout<<"Data member in Object of class sample1 is larger"<<endl ;
autre
cout<<"Data member in Object of class sample2 is larger"<<endl ;
}
void main()
{
échantillon1 obj1(3) ;
échantillon2 obj2(5) ;
max(obj1,obj2) ;
}

Écrire un programme pour additionner des nombres complexes à l'aide de la fonction friend

#include<iostream>
using namespace std ;
classe complexe
{
float real,img ;
public :
complexe() ;
complexe(float x,float y)
ami complexe add_complex(complexe c1,complexe c2) ;
};
complexe::complexe()
{
real=img=0 ;
}
complex::complex(float x,float y)
{
real=x;img=y ;
}
complexe add_complex(complexe c1,complexe c2)
{
t complexe ;
t.real=c1.real+c2.real ;
t.img=c1.img+c2.img ;
retourner t ;
}
void complex::display ()
{
if(img<0)
{img=-img ;
cout<real<<"-i"<<img<<endl
} else { cout<<real<<"+i"<<img<<<endl
}
}
int main()
{
complexe obj1(2,3) ;
complexe obj2(-4,-6) ;
complexe obj3=add_compex(obj1,obj2) ;
obj3.display() ;
retour 0 ;
}

Classe amie:Une classe peut également être déclarée amie d'une autre classe. Lorsque nous créons une classe
amie, toutes les fonctions membres de la classe amie deviennent également amies de l'autre classe. Pour ce
faire, il faut que l'ami qui devient la classe soit d'abord déclaré ou défini (déclaration préalable).
#include <iostream.h>
classe sample_1
{
friend class sample_2;//déclarer la classe amie
int a,b ;
public :
void getdata_1()
{
cout<<"Enter A & B values in class sample_1" ;
cin>>a>>b ;
}
void display_1()
{
cout<<"A="<<a<<endl ;
cout<<"B="<<b<<endl ;
}

};
classe sample_2
{
int c,d,sum ;
échantillon_1 obj1 ;
public :
void getdata_2()
{
obj1.getdata_1() ;
cout<<"Enter C & D values in class sample_2" ; cin>>c>>d ;
}
void sum_2()
{
sum=obj1.a+obj1.b+c+d ;
}

void display_2()
{
cout<"A="<<obj1.a<<endl ;
cout<"B="<<obj1.b<<endl ;
cout<<"C="<<c<<endl ;
cout<<"D="<<d<<endl ;
cout<"SUM="<<sum<<endl ;
}
};
int main()
{
échantillon_1 s1 ;
s1.getdata_1() ;
s1.display_1() ;
échantillon_2 s2 ;
s2.getdata_2() ;
s2.sum_2() ;
s2.display_2() ;
}

Entrez les valeurs A et B dans la classe sample_1:1 2


A=1
B=2
Entrez les valeurs A et B dans la classe sample_1:1 2 3 4
Entrez les valeurs C et D dans la classe sample_2:A=1
B=2
C=3
D=4
SUM=10
UNITÉ -3

Constructeurs, destructeurs, héritage :


Introduction aux constructeurs, aux constructeurs par défaut, aux constructeurs paramétrés, aux
constructeurs par copie, aux constructeurs multiples dans une classe, aux destructeurs.
Héritage :Introduction à l'héritage, définition des classes dérivées, héritage simple, héritage multiple,
héritage à plusieurs niveaux, héritage hiérarchique, héritage hybride.
D
Introduction aux constructeurs : Le C++ fournit une fonction membre spéciale appelée
constructeur qui permet à un objet de s'initialiser lorsqu'il est créé.
Définition:- Un constructeur est une fonction membre spéciale dont la tâche est d'initialiser les objets de
sa classe. Il est spécial parce que son nom est le même que celui de la classe. Le constructeur est
invoqué chaque fois qu'un objet de la classe qui lui est associée est créé. Il est appelé constructeur parce
qu'il construit les valeurs des données membres de la classe.
Un constructeur est déclaré et défini comme suit :

integer obj1 ; => crée non seulement l'objet obj1 mais initialise également ses membres de données m et n à
zéro. Il n'est pas nécessaire d'écrire une déclaration pour invoquer la fonction constructeur.
CARACTÉRISTIQUES DU
CONSTRUCTEUR
> Elles sont invoquées automatiquement lors de la création des objets.
> Ils n'ont pas de type de retour, pas même void.
Elles ne peuvent pas être héritées, bien qu'une classe dérivée puisse appeler le
constructeur de la classe de base.
> Comme d'autres fonctions c++, elles peuvent avoir des arguments par défaut.

> Les constructeurs ne peuvent pas être virtuels.

>
Ils font des "appels implicites" aux opérateurs new et delete lorsque l'allocation de mémoire est
nécessaire.
Les constructeurs sont de trois types :
1. Constructeur par défaut
2. Constructeur paramétré
3. Constructeur de copie
1 Constructeur par défaut : Un constructeur qui n'accepte aucun paramètre est appelé constructeur par
défaut.
#include<iostream.h>
#include<conio.h> classe item
{
int m,n ;
public :
item()
{
m=10 ;
n=20 ;
}
void put() ;
};
void item::put() {
cout<<m<<n ;
}
void main()
{
article t ;
t.put() ;
getch() ;
}
2 Constructeurs paramétrés:- Lesconstructeurs qui prennent des paramètres sont appelés
constructeurs paramétrés.
#include<iostream.h>
élément de classe
{
int m,n ;
public :
item(int x, int y)
{

m=x ;
n=y ;
}

};
Lorsqu'un constructeur a été paramétré, la déclaration d'objet telle que item t ; peut ne pas
fonctionner. Nous devons passer les valeurs initiales comme arguments à la fonction constructeur lors
de la déclaration d'un objet. Cela peut se faire de deux manières : item t=item(10,20) ; //appel explicite

item t(10,20) ; //appel implicite


Eg :
#include<iostream.h>
#include<conio.h>
élément de classe
{
int m,n ;
public :
item(int x,int y)
{

m=x ;
n=y ;
}

void put() ;
};
void item::put()
{
cout<<m<<n ;
}
void main()
{
article t1(10,20) ;
item t2=item(20,30) ;
t1.put() ;
t2.put() ;
getch() ;
}
3 Constructeur de copie : Un constructeur de copie est utilisé pour déclarer et initialiser un
objet à partir d'un autre objet.
Eg :
poste t2(t1) ;
ou
article t2=t1 ;

1. Le processus d'initialisation par le biais d'un constructeur de copie est connu sous le nom
d'initialisation par copie.
2. t2=t1 n'invoquera pas le constructeur de copie. t1 et t2 sont des objets, affecte les valeurs de t1 à t2.
3. Un constructeur de copie prend comme référence un objet de la même classe que lui.
un argument. #include<iostream.h>
échantillon de classe
{
int n ;
public :
échantillon()
{
n=0 ;
}
sample(int a)
{
n=a ;
}
sample(sample &x)
{
n=x.n ;
}
void display()
{
cout<<n ;
}
};
void main()
{
échantillon A(100) ;
l'échantillon B(A) ;
échantillon C=A ;
échantillon D ;
D=A ;
A.display() ;
B.display() ;
C.display() ;
D.display() ;
}

Sortie : 100 100 100 100

Plusieurs constructeurs dans une classe : Plusieurs constructeurs peuvent être déclarés dans une
classe. Il peut y avoir un nombre quelconque de constructeurs dans une classe.
classe complexe
{
float real,img ;
public :
complex()//constructeur par défaut
{

real=img=0 ;
}

complex(float r)//constructeur paramétré à un seul paramètre


{

real=img=r ;
}

complex(float r,float i) //Constructeur paramétré à deux paramètres


{

real=r;img=i ;
}
complex(complex&c)//copie du constructeur
{
real=c.real ;
img=c.img ;

}
complexe sum(complexe c ) {
t complexe ;
t.real=real+c.real ;
t.img=img+c.img ;
retourner t ;
}
void show()
{
Si(img>0)
cout<<real<<"+i"<<img<<endl ;
autre
{
img=-img ;
cout<<real<<"-i"<<img<<endl ;
}

};
void main()
{
complexe c1(1,2) ;
complexe c2(2,2) ;
compex c3 ;
c3=c1.sum(c3) ;
c3.show() ;

DESTRUCTORS:Un destructeur est utilisé pour détruire les objets qui ont été créés par un constructeur.
Comme le constructeur, le destructeur est une fonction membre dont le nom est le même que celui de la
classe, mais précédé d'un tilde.
Eg : ~item() { }
1. Un destructeur ne prend aucun argument et ne renvoie aucune valeur.
2. Il sera invoqué implicitement par le compilateur à la sortie du programme pour nettoyer la mémoire qui
n'est plus accessible.
3. C'est une bonne pratique de déclarer des destructeurs dans un programme, car cela libère de l'espace
mémoire pour une utilisation future.

#include<iostream>
using namespace std ;
classe Marques
{
public :
maths int ;
la science int ;

//constructeur
Marks() {
cout << "Inside Constructor"<<endl ;
cout << "Objet C++ créé"<<endl ;
}

/Destructeur
~Marks() {
cout << "Inside Destructor"<<endl ;
cout << "C++ Object destructed"<<endl ;
}
};

int main( )
{
Marques m1 ;
Marques m2 ;
retour 0 ;
}

Sortie :
A l'intérieur du constructeur
Objet C++ créé
A l'intérieur du constructeur
Objet C++ créé
Destructeur interne
Destruction d'un objet C++
Destructeur interne
Destruction d'un objet C++

HÉRITAGE : . Le mécanisme de dérivation d'une nouvelle classe à partir d'une ancienne est appelé
héritage ou dérivation. L'ancienne classe est appelée classe de base et la nouvelle classe est appelée classe
dérivée ou sous-classe. La classe dérivée hérite de tout ou partie des caractéristiques de la classe de base.
Une classe peut également hériter de propriétés de plus d'une classe ou de plus d'un niveau. La
réutilisation est une caractéristique importante de la POO

Une classe dérivée peut être définie en spécifiant sa relation avec la classe de base en plus de ses propres
détails.

class derived-class-name : visibility-mode base-class-name {

Les deux points indiquent que le nom de la classe dérivée est dérivé du nom de la classe de base. Le mode de
visibilité est facultatif et, s'il est présent, peut être private, protected ou public. La valeur par défaut est privée.
Le mode de visibilité spécifie si les caractéristiques de la classe de base sont dérivées de manière privée ou
publique.
//dérivation privée
class ABC : private XYZ {
membres de l'ABC ;
};
classe ABC:public XYZ
{
membres de l'ABC ;
};
//dérivation publique

class ABC:protected XYZ { // membres de dérivation protégés de ABC ;


};
classe ABC:XYZ //privé par défaut
{
membres de l'ABC ;
};
Lorsqu'une classe de base est héritée de façon privée par une classe dérivée, les membres publics de la
classe de base ne peuvent être accédés que par les fonctions membres de la classe dérivée. Les membres privés
de la classe de base sont inaccessibles aux objets de la classe dérivée.
Lorsqu'une classe de base est protégée et héritée par une classe dérivée, les membres publics de la
classe de base ne peuvent être accédés que par les fonctions membres de la classe dérivée, tandis que les
membres privés de la classe de base sont inaccessibles aux objets de la classe dérivée. Si les membres privés de
la classe de base doivent être hérités par la classe dérivée, ils doivent être déclarés comme protégés.
Lorsque la classe de base est héritée publiquement, les membres publics de la classe de base
deviennent des membres publics de la classe dérivée et sont donc accessibles aux objets de la classe dérivée.
Dans les deux cas, les membres privés ne sont pas hérités et, par conséquent, les membres privés d'une classe de
base ne deviendront jamais les membres de la classe dérivée.
Dans l'héritage, certains éléments de données et fonctions membres de la classe de base sont "hérités"
dans la classe dérivée. Nous pouvons ajouter nos propres données et fonctions membres et ainsi étendre la
fonctionnalité de la classe de base. L'héritage, lorsqu'il est utilisé pour modifier et étendre les capacités des
classes existantes, devient un outil très puissant pour le développement incrémental de programmes.

Visibilité des membres hérités


Visibilité de l'élate dérivée
Baur cUu* vitibility
Dérivation
publique Dérivation privée Dérivation protégée
Privé —♦ Non hérité Non hérité
Sans héritage Protégé
Protégé ♦ Privé Protégé
Public — Public Privé Protégé

Types d'héritage : 1. héritage unique 2. héritage à plusieurs niveaux 3. héritage multiple 4. héritage hybride 5.
Héritage hiérarchique.
1) HÉRITAGE UNIQUE : une classe dérivée hérite d'une seule classe de base. C'est la forme la plus simple
d'héritage.

A / /Classe de base

B //Classe dérivée
#include<iostream> using namespace std ; class A { public : int a,b ; void get() { cout<<"Entrez deux valeurs
entières quelconques"<<endl ; cin>>a>>b ;
} };

class B:public A {
int c ;
public :
void add()
{ c=a+b ;
cout<a<<"+"<<b<"="<<c ;
}
};

int main()
{
Bb;
b.get() ;
b.add() ;
}

Sortie :
Entrez deux valeurs entières quelconques
12
1+2=3
2) HÉRITAGE MULTINIVEAU : dans ce type d'héritage, la classe dérivée hérite d'une classe qui, à son tour,
hérite d'une autre classe. La super classe pour l'un, c'est la sous classe pour l'autre.

#include<iostream.h>
classe A
{
public :
int a,b ;
void get()
{
cout<<"Entrez deux valeurs entières quelconques"<<endl ;
cin>>a>>b ;
}
};

classe B:public A
{
public :
int c ;
void add()
{
c=a+b ;
}
};

classe C:public B
{
public :
void show()
{
cout<a<<"+"<<b<"="<<c ;
}
};
int main()
{
Cc;
c.get() ;
c.add() ;
c.show() ;
}
Sortie :
Entrez deux valeurs entières quelconques
12 14
12+14=26
3 Héritage multiple :dans ce type d'héritage, une seule classe dérivée peut hériter de deux classes de base
ou plus.

Syntaxe
: classe D : visibilité A, visibilité B,.... {

#include<iostream.h>
classe A
{
public :
int a ;
void getA()
{
cout<<"Enter an Integer value"<<endl ; cin>>a ;
}
};
classe B
{
public :
int b ;
void getB()
{
cout<<"Enter an Integer value"<<endl ; cin>>b ;
}
};

classe C:public A,public B


{
public :
int c ;
void add()
{
c=a+b ;
cout<a<<"+"<<b<"="<<c<<endl ;
}
};
int main()
{
C obj ;
obj.getA() ;
obj.getB() ;
obj.add() ;
}
Entrer un nombre entier
valeur 12 Entrer un
Valeur entière 13 12+13=25

4 Héritage hybride: L'héritage hybride est une combinaison de deux ou plusieurs héritages tels que
l'héritage simple, multiple, multiniveau ou hiérarchique.
#include<iostream.h>
classe arithmétique
{
protégé :
int num1, num2 ;
public :
void getdata()
{
cout<<"Pour l'ajout :";
cout<"\nEntrez le premier nombre : " ;
cin>>num1 ;
cout<"\nEntrez le deuxième nombre : " ;
cin>>num2 ;
}
};
classe plus:public arithmétique
{
protégé :
int sum ;
public :
void add()
{
somme=num1+num2 ;
}
};
classe moins
{
protégé :
int n1,n2,diff ;
public :
void sub()
{
cout<"\nPour la soustraction :";
cout<"\nEntrez le premier nombre : " ;
cin>>n1 ;
cout<"\nEntrez le deuxième nombre : " ;
cin>>n2 ;
diff=n1-n2 ;
} };
classe result:public plus, public minus
{
public :
void display()
{

cout<"\nSomme de "<<num1<<" et "<<num2<"="<<sum ;


cout<"\nLa différence entre "<<n1<<" et "<<n2<"= "<<diff ;
}
};
int main()
{
résultat z ;
z.getdata() ;
z.add() ;
z.sub() ;
z.display() ;
}

Pour l'ajout :
Saisir le premier chiffre : 1

Saisir le deuxième chiffre : 2

Pour la soustraction :
Saisir le premier chiffre : 3

Saisir le deuxième chiffre : 4

Somme de 1 et 2= 3
Différence entre 3 et 4= -1

5 Héritage hiérarchique : l'héritage est une méthode de transmission dans laquelle une ou plusieurs
classes dérivées sont dérivées d'une classe de base commune.

#include<iostream.h> class A //Base Class {


public :
int a,b ;
void getnumber()
{
cout<"\nEntrez le numéro :\t" ; cin>>a ;
}
};
class B : public A //Dérivé de la classe 1
{
public :
void square()
{
getnumber() ; //Appelle la propriété de la classe de base cout<"\n\n- Carré du nombre :\t"<<(a*a) ;
}
};
class C :public A //Classe dérivée 2
{
public :
void cube()
{
getnumber() ; //Appelle la propriété de la classe de base cout<"\n\nCube du nombre :::\t"<<(a*a*a) ;
}
};
int main()
{
B b1 ; //b1 est un objet de la classe dérivée 1
b1.square() ; //appeler une fonction membre de la classe B C c1 ; //c1 est un objet de la classe dérivée 2
c1.cube( ) ; //appeler une fonction membre de la classe C }
Entrer le numéro : 2
Carré du nombre : 4

Entrer le numéro : 3

Cube du nombre :: : 27
UNITÉ -4

Pointeurs, fonctions virtuelles et polymorphisme:Introduction, gestion de la mémoire, nouvel opérateur


et opérateur de suppression, pointeurs sur des objets, ce pointeur, pointeurs sur des objets, pointeurs sur des
objets, pointeurs sur des objets.
Classes dérivées, polymorphisme, polymorphisme à la compilation, polymorphisme à l'exécution, classes
virtuelles, classes dérivées, classes dérivées, classes dérivées, classes dérivées, classes dérivées, classes
dérivées, classes dérivées.
Fonctions, fonctions virtuelles pures, classes de base virtuelles, destructeurs virtuels, fonctions
Surcharge, surcharge des opérateurs, règles de surcharge des opérateurs - opérateurs binaires et unaires.

Introduction à la gestion de la mémoire :

ALLOCATION ET DÉALLOCATION DYNAMIQUES DE LA MÉMOIRE (nouvelles


et suppressions)
Le langage C utilise les fonctions malloc() et calloc() pour allouer dynamiquement de la mémoire au moment
de l'exécution. Il utilise la fonction free() pour désallouer la mémoire allouée dynamiquement.
Le langage C++ prend en charge ces fonctions et définit deux opérateurs unaires, new et delete , qui permettent d'allouer et de
supprimer des données.
désallouer la mémoire d'une manière plus efficace et plus facile.
Un objet peut être créé à l'aide de new et détruit à l'aide de delete.

Un objet de données créé à l'intérieur d'un bloc avec new, restera en existence jusqu'à ce qu'il soit
explicitement
détruit en utilisant la fonction de suppression.
nouvel opérateur:-
L'opérateur new peut être utilisé pour créer des objets de n'importe quel type ; il alloue donc
suffisamment de mémoire pour contenir les données des objets et renvoie l'adresse de la mémoire
allouée. Syntaxe :

pointeur-variable = nouveau type de données ;

Ex : int *p = new int ;

>
Pour créer un espace mémoire pour les tableaux : pointeur-variable = nouveau type de données [taille]
;

Ex : int *p = new int[10] ;

opérateur de suppression:
Si la variable ou l'objet n'est plus requis ou nécessaire, il est détruit par l'opérateur "delete", ce qui
libère une certaine quantité de mémoire pour un usage ultérieur. Synatx :

supprimer le pointeur-variable ;

Ex : supprimer p ;

>
Si nous voulons libérer un
array : delete [size] pointeur-variable ;
Programme : écrire un programme pour trouver la somme d'une liste d'entiers #include<iostream> using
namespace std ; int main()
{
int n,*p ;
cout<<"Enter array size :";
cin>>n ;
p=nouveau int[n] ;
cout<<"Entrez la liste des entiers"<<endl ;
for(int i=0;i<n;i++)
cin>>p[i] ;
//logique de la sommation
int s=0 ;
for( int i=0;i<n;i++)
s=s+p[i] ;
cout<<"La somme des éléments du tableau est de" ;
cout<<s ;
supprimer [ ]p ;
retour 0 ;
}
Entrer la taille du tableau : 5
Saisir une liste de nombres entiers
1 2345
La somme des éléments du tableau est
15

Membre Opérateur de déréférencement:-


1. Pointeur vers un déclarateur de ::*
2. membre
Pointeur vers l'opérateur membre ->*
3. Pointeur vers l'opérateur membre .*
Pointeur vers un déclarateur de membre ::*
Cet opérateur est utilisé pour déclarer un pointeur sur un membre de la classe #include<iostream.h>
échantillon de classe
{public :
int x ;
};
int main()
{ échantillons ; //objet
int sample ::*p;//déclinaison du pointeur
s.*p=10 ; //correct
cout<<s.*p ;
}
Sortie:10
2 Pointeur vers l'opérateur membre ->*
#include<iostream.h>
échantillon de classe
{
public :
int x ; void
display() {
cout<"x="<<x<<endl ;
}
};
int main()
{
échantillons ; //objet
échantillon *ptr ;
int sample::*f=&sample::x ;
s.x=10 ;
ptr=&s ;
cout<<ptr->*f ;
ptr->display() ;
}

3 . Pointeur vers l'opérateur membre .*


#include<iostream.h>
échantillon de classe
{
public :
int x ;
};
int main()
{

échantillons ; //objet
int sample ::*p;//déclinaison du pointeur
s.*p=10 ; //correct
cout<<s.*p ;
}

Pointeurs vers des objets:Les pointeurs vers des objets sont utiles pour créer des objets au moment de
l'exécution. Pour accéder aux membres, l'opérateur de flèche ( ) et l'opérateur de référencement ou
d'indirection (*) sont utilisés.
Déclaration du pointeur.
nom de classe*ptr
ex :
item *obj ;
Ici, obj est un pointeur sur un objet de type item.

élément de classe
{
code int ;
prix flottant ;
public :
void getdata(int a,float b)
{
code=a ;
prix=b ;
}
void show()
{
cout<"code :"<<code<"\n"<<"Prix :"<<prix<<endl ;
}
};

Déclaration d'un objet et d'un pointeur sur un élément de la classe : item obj;
item *ptr=&obj ;
Le membre est accessible comme suit.
a) Accès aux membres à l'aide de l'opérateur point obj.getdata(101,77.7) ; obj.show() ;

b) à l'aide d'un pointeur


ptr->getdata(101,77.7);
ptr->show() ;
c)Utilisation de l'opérateur de référence et de l'opérateur point (*ptr).getdata(101,77.7) ;
(*ptr).show() ;

Création d'un tableau d'objets à l'aide d'un pointeur : item *ptr=new item[10] ;

La déclaration ci-dessus crée un espace mémoire pour un tableau de 10 objets de type item.
#include<iostream.h> classe item
{
code int ;
prix flottant ;
public :
void getdata(int a,float b) {
code=a ; prix=b ;
}
void show()
{
cout<code<<"\t"<<prix<<endl ;
}
};
int main()
{
int n ;
int cd ;
float pri ;
cout<<"Entrez le nombre d'objets à créer :";
cin>>n ;
item *ptr=nouvel item[n] ;
article *p ;
p=ptr ;
for(int i=0;i<n;i++) {
cout<<"Enter data for object"<<i+1 ;
cout<"\nEntrez le code :";cin>>cd ;
cout<<"Entrez le prix :";cin>>pri ;
p->getdata(cd,pri) ;
p++ ;
}
p=ptr ;
cout<<"Les données contenues dans les différents objets sont "<<endl ;
cout<<"Sno\tCode\tPrice\n" ;
for(i=0;i<n;i++)
{
cout<i+1<<"\t" ;
ptr->show() ;
ptr++ ;
}
retour 0 ;
}

Pointeurs vers les classes dérivées : Des pointeurs peuvent être déclarés vers une classe dérivée. Ils
peuvent être utilisés pour accéder aux membres de la classe de base et de la classe dérivée. Un pointeur de
classe de base peut également être utilisé pour pointer vers un objet d'une classe dérivée, mais il ne peut
accéder qu'aux membres hérités de la classe de base.

#include<iostream.h>
classe de base
{
public :
int a ;
void get_a(int x)
{
a=x ;
}
void display_a()
{
cout<"Dans la base"<<"\N"<<"a="<<a<<endl ;
}
};
classe derived:public base
{
int b ;
public :
void get_ab(int x,int y)
{
a=x ;
b=y ;
}
void display_ab()
{
cout<"In Derived"<<"\n"<<"a="<<a<<"\nb="<<b<endl ;
}
};
int main()
{
base b ;
base *bptr ;
bptr=&b;//pointe sur l'objet de la classe de base
bptr->get_a(100) ;
bptr->display_a() ;

dérivé d ;
dérivé *dptr ;
dptr=&d;//pointe sur l'objet de la classe dérivée

dptr->get_a(400) ;
dptr->display_a() ;
dptr->get_ab(300,200);
dptr->display_ab() ;

bptr=&d;//pointe vers l'objet de la classe dérivée bptr->get_a(400) ;


bptr->display_a() ;

retour 0 ;
}
Sortie :
En base
a=100

En base
a=400
En dérivé
a=300
b=200
En base
a=400

POLYMORPHISME D'EXÉCUTION À L'AIDE DE FONCTIONS VIRTUELLES


Liaison statique et dynamique
Le polymorphisme signifie "un nom" - "plusieurs formes".
Les fonctions membres surchargées sont "sélectionnées" pour être invoquées en fonction des arguments
correspondants, qu'il s'agisse du type ou du nombre. Ces informations sont connues du compilateur au moment
de la compilation et le compilateur est en mesure de sélectionner la fonction appropriée pour un appel
particulier au moment de la compilation. C'est ce que l'on appelle le " Early Binding" ou " Static Binding "
ou " Static Linking". Également connu sous le nom de polymorphisme de compilation. La liaison anticipée
signifie qu'un objet est lié à son appel de fonction au moment de la compilation.
Il serait intéressant de pouvoir sélectionner la fonction membre appropriée pendant l'exécution du
programme. C'est ce qu'on appelle le polymorphisme d'exécution. Le C++ utilise un mécanisme connu sous
le nom de fonction virtuelle pour réaliser le polymorphisme au moment de l'exécution.
Au moment de l'exécution, lorsque l'on sait quelles sont les classes d'objets considérées, la version
appropriée de la fonction est invoquée. Étant donné que la fonction est liée à une classe particulière beaucoup
plus tard après la compilation, ce processus est appelé "late binding" (liaison tardive). On parle également de
liaison dynamique car la sélection de la fonction appropriée se fait dynamiquement au moment de
l'exécution.

Fonction Opérateur Virtuel


Surcharge Surcharge Fonctions
FONCTIONS VIRTUELLES

Le polymorphisme est la propriété par laquelle des objets appartenant à des classes différentes sont
capables de répondre au même message, mais sous des formes différentes. Une exigence essentielle du
polymorphisme est donc la possibilité de se référer à des objets sans tenir compte de leurs classes.

Lorsque nous utilisons le même nom de fonction dans la classe de base et dans la classe dérivée, la
fonction de la classe de base est déclarée comme virtuelle à l'aide du mot-clé virtual précédant sa déclaration
normale.

Lorsqu'une fonction est rendue virtuelle, le C++ détermine la fonction à utiliser au moment de l'exécution en
fonction du type d'objet pointé par le pointeur de base, plutôt que du type du pointeur. Ainsi, en faisant pointer
le pointeur de base sur différents objets, nous pouvons exécuter différentes versions de la fonction virtuelle.

#include<iostream.h>
classe Base
{
public :
void display()
{
cout<<"Base d'affichage" ;
}
virtual void show()
{
cout<<"Show Base" ;
}
};
classe Derived : public Base
{
public :
void display()
{
cout<<"Affichage dérivé" ;
}
void show()
{
cout<<"show derived" ;
}
};

void main()
{
Base b ;
Dérivé d ;
Base *ptr ;
cout<<"ptr pointe vers Base" ;
ptr=&b ;
ptr->display() ; //appelle Base
ptr->show( ) ; //appelle Base
cout<<"ptr points to derived" ;
ptr=&d ;
ptr->display() ; //appelle Base
ptr->show() ; //classe Dérivé
}

Sortie :

ptr pointe vers Base


Socle d'affichage
Montrer la base

ptr pointe vers Derived

Socle d'affichage
Afficher les dérivés

Lorsque ptr pointe sur l'objet d, l'instruction ptr->display() ; n'appelle que la fonction
associée à la base, c'est-à-dire. Base::display()

alors que la déclaration

ptr->show() ;

appelle la version dérivée de show(). Cela est dû au fait que la fonction display() n'a pas été rendue virtuelle
dans la classe Base.

Règles pour les fonctions virtuelles :

Lorsque des fonctions virtuelles sont créées pour mettre en œuvre la liaison tardive, il convient de
respecter certaines règles de base qui satisfont aux exigences du compilateur.

1. Les fonctions virtuelles doivent être membres d'une classe.


2. Ils ne peuvent pas être des membres statiques.
3. On y accède en utilisant des pointeurs d'objets.
4. Une fonction virtuelle peut être l'amie d'une autre classe.
5. Une fonction virtuelle dans une classe de base doit être définie, même si elle n'est pas utilisée.
6. Les prototypes de la version de la classe de base d'une fonction virtuelle et de toutes les versions des
classes dérivées doivent être identiques. Le C++ les considère comme des fonctions surchargées et le
mécanisme des fonctions virtuelles est ignoré.
7. Nous ne pouvons pas avoir de constructeurs virtuels, mais nous pouvons avoir des destructeurs
virtuels.
8. Alors qu'un pointeur de base pointe vers n'importe quel type d'objet dérivé, l'inverse n'est pas vrai,
c'est-à-dire que nous ne pouvons pas utiliser un pointeur vers une classe dérivée pour accéder à un
objet du type de la classe de base.
9. Lorsqu'un pointeur de base pointe vers une classe dérivée, son incrémentation ou sa décrémentation ne
le fera pas pointer vers l'objet suivant de la classe dérivée. Il n'est incrémenté ou décrémenté que par
rapport à son type de base. Par conséquent, nous ne devons pas utiliser cette méthode pour déplacer le
pointeur vers l'objet suivant.
10. Si une fonction virtuelle est définie dans la classe de base, elle ne doit pas nécessairement être
redéfinie dans la classe dérivée. Dans ce cas, les appels invoqueront la fonction de base.
SURCHARGE

SURCHARGE DE L'OPÉRATEUR
Le C++ permet de donner aux opérateurs une signification particulière pour un type de données. Le
mécanisme permettant de donner ces significations spéciales à un opérateur est connu sous le nom de
surcharge d'opérateur. Nous pouvons surcharger tous les opérateurs à l'exception des suivants :
Opérateur d'accès aux membres de la classe ("." Et "
.*") Opérateur de résolution de portée ": :"
Opérateur de taille (sizeof)
Opérateur conditionnel
Pour définir une tâche supplémentaire pour un opérateur, précisez ce qu'elle signifie par rapport à la
classe à laquelle l'opérateur est appliqué. Cela se fait à l'aide d'une fonction spéciale, appelée fonction
opérateur. Le processus de surcharge comporte les étapes suivantes :
1. Créez une classe qui définit le type de données à utiliser dans l'opération de surcharge.
2. Déclarez la fonction opérateur op() dans la partie publique de la classe. Il peut s'agir d'une fonction
membre ou d'une fonction amie.
3. Ici, op est l'opérateur à surcharger.
4. Définir la fonction de l'opérateur pour mettre en œuvre les opérations requises.
Ex :
complexe complexe::operator+(complexe c)
{
t complexe ;
t.real=real+c.real ;
t.img=img+c.img ;
retourner t ;
}
Concept de surcharge de l'opérateur
L'une des caractéristiques uniques du C++ est la surcharge des opérateurs. L'application de la surcharge aux
opérateurs permet de répondre différemment à un même opérateur. Par exemple, l'opérateur + peut être utilisé
comme opérateur de concaténation et comme opérateur supplémentaire.

C'est-à-dire que 2+3 signifie 5 (addition), alors que


"2"+"3" signifie 23 (concaténation).
L'exécution de plusieurs actions à l'aide d'un seul opérateur est appelée surcharge d'opérateur. Nous
pouvons attribuer une fonction définie par l'utilisateur à un opérateur. Nous pouvons modifier la fonction d'un
opérateur, mais il n'est pas recommandé de modifier les fonctions réelles de l'opérateur. Nous ne pouvons pas
créer de nouveaux opérateurs en utilisant ce chargement d'opérateur.
Le concept de surcharge de l'opérateur peut être appliqué dans les deux domaines principaux suivants
(avantages)
1. Extension de l'utilisation des opérateurs
2. Conversions de données
Règles à respecter en cas de surcharge de l'opérateur
1 Seuls les opérateurs existants peuvent être surchargés.
2 Les opérateurs surchargés doivent avoir au moins un opérande qui est un opérateur défini par
l'utilisateur.
3 Nous ne pouvons pas modifier la signification fondamentale d'un opérateur.
4 L'opérateur surchargé doit respecter les caractéristiques minimales de l'opérateur d'origine.
5 Lors de l'utilisation de la surcharge de l'opérateur binaire par le biais d'une fonction membre,
l'opérande de gauche doit être un objet de la classe concernée.
Le nombre d'arguments dans la liste d'arguments de l'opérateur surchargé dépend

1. La fonction de l'opérateur doit être une fonction membre ou une fonction amie.
2. Si la fonction opérateur est une fonction amie, elle aura un argument pour l'opérateur unaire.
& deux arguments pour l'opérateur binaire
3. Si la fonction opérateur est une fonction membre, elle aura zéro argument pour l'opérateur
unaire et un argument pour l'opérateur binaire.

Surcharge des opérateurs unaires


Un opérateur unaire est un opérateur qui travaille sur un seul opérande. Par exemple, ++ est un opérateur unaire,
il ne prend qu'un seul opérande (c++). Ainsi, lors de la surcharge d'un opérateur unaire, celui-ci ne prend aucun
argument (car l'objet lui-même est considéré comme un argument).

Syntaxe de l'opérateur unaire (à l'intérieur d'une classe)

opérateur de type retour operatorymbol( )


{
//corps de la fonction
}

Ex :
void operator-()
{
real=-real ;
img=-img ;
}
Syntaxe de l'opérateur unaire (en dehors d'une classe)
type de retour classname::operator operatorymbol( )
{
//corps de la fonction
}

Exemple 1:-
void operator++()
{
contre++ ;
}

Exemple 2:-

void complex::operator-()
{

real=-real ;
img=-img ;
}

Le programme simple suivant explique le concept de surcharge unaire.


#include < iostream.h >
#include < conio.h >
// Opérateur de programme
Surcharge de la classe fact
{
int a ;
public :
fait ()
{

a=0
} fact; (int i) {
a=i ;
}
fait opérateur !()
{
int f=1,i ;
fait t ;
for (i=1;i<=a;i++)
{
f=f*i ;
}
t.a=f ;
retourner t ;
}
void display()
{
cout<<"La factorielle "<< a ;
}
};
void main()
{
int x ;
cout<<"enter a number" ;
cin>>x ;
fait s(x),p ;
p=!s ;
p.display() ;
}

Résultat du programme ci-dessus :


Entrer un chiffre 5
La factorielle d'un nombre donné 120

Explication :
Nous avons pris " !" comme opérateur de surcharge. Ici, le nom de la classe est un fait. Constructeur sans
paramètres pour prendre la valeur initiale de "x" à 0. Constructeur avec paramètre pour prendre la valeur de
"x" . Nous avons créé deux objets, l'un pour effectuer la factorielle et l'autre pour retourner la factorielle. Ici, le
nombre de paramètres d'une fonction surchargée est de 0. La factorielle est un opérateur unaire car elle opère
sur un seul élément de données. La surcharge de l'opérateur permet de trouver la factorielle de l'objet. La
fonction d'affichage pour l'impression du résultat.

Surcharge de l'opérateur unaire -

Exemple 1:-
Ecrire un programme pour surcharger l'opérateur unaire -
#include<iostream>
using namespace std ;
classe complexe
{
float real,img ;
public :
complexe() ;
complexe(float x, float y) ;
void display() ;
void operator-() ;
};
complexe::complexe()
{
real=0;img=0 ;
}
complex::complex(float x, float y)
{
real=x ;
img=y ;
}
void complex::display()
{
int imag=img ;

if(img<0)
{
imag=-img ;
cout<real<<" -i"<<imag<<endl ;
}
autre
cout<<real<<" +i"<<img<<endl ;
}
void complex::operator-()
{
real=-real ;
img=-img ;
}
int main()
{
complexe c(1,-2) ;
c.display() ;
cout<<"Après Unary - operation\n" ;
-c ;
c.display() ;
}

Exemple 2:-
#include<iostream.h>
using namespace std ;
espace classe
{
int x,y,z ;
public :
void getdata(int a,int b,int c) ;
void display() ;
void operator-() ;
};
void space : : getdata(int a,int b,int c)
{
x=a ;
y=b ;
z=c ;
}
void space : : display()
{
cout<"x="<<x<<endl ;
cout<<"y="<<y<<endl ;
cout<<"z="<<z<<endl ;
}
void space : : operator-()
{
x=-x ;
y=-y ;
z=-z ;
}
int main()
{
espace s ;
s.getdata(10,-20,30);
s.display() ;
-s ;
cout<<"après la négation" ;
s.display() ;
}

Sortie :
x=10
y=-20
z=30
après la négation
x=-10
y=20
z=-30

Il est possible de surcharger l'opérateur unaire moins en utilisant une fonction amie comme suit :
friend void operator-(space &s) ;

Exemple 3:-
Opérateur unaire moins utilisant une fonction amie
#include<iostream.h>
#include<iostream.h>
using namespace std ;
espace classe
{
int x,y,z ;
public :
void getdata(int a,int b,int c) ;
void display() ;
ami void operator-(space &) ;
};
void space : : getdata(int a,int b,int c)
{
x=a ;
y=b ;
z=c ;
}

void space : : display()


{
cout<x<<" "<<y<" "<<z<<endl ;
}
void operator-(space &s)
{
s.x=-s.x ;
s.y=-s.y ;
s.z=-s.z ;
}

int main()
{
espace S ;
S.getdata(10,-20,30);
S.display() ;
-S ;
cout<<"après la négation" ;
S.display() ;
}

Sortie :
10 -20 30
après la négation
-10 20-30

Surcharge des opérateurs binaires


Un opérateur binaire est un opérateur qui travaille sur deux opérandes. Par exemple, + est un opérateur binaire,
il prend un seul opérande (c+d). Ainsi, lors de la surcharge d'un opérateur binaire, celui-ci prend un argument
(l'un est l'objet lui-même et l'autre est l'argument transmis).

Syntaxe de l'opérateur binaire (à l'intérieur d'une classe) return-type operator


operatorymbol(argument) {
//corps de la fonction
}
Syntaxe pour la définition d'un opérateur binaire (en dehors d'une classe) return-type
classname::operatorymbol(argument) {
//corps de la fonction
}

Exemple opérateur complexe+(complexe s)


{
t complexe ;
t.real=real+s.real ;
t.img=img+s.img ;
retourner t ;
}
Le programme suivant explique la surcharge des opérateurs binaires :
#include < iostream.h >
#include < conio.h >
somme des classes
{
int a ;
public :
somme()
{
a=0 ;
}
sum(int i)
{
a=i ;
}
opérateur de somme+(somme p1)
{
somme t ;
t.a=a+p1.a ;
retourner t ;
}
void main ()
{
cout<<"Entrez deux chiffres :"
int a,b ;
cin>>a>>b ;
somme x(a),y(b),z ;
z.display() ;
z=x+y ;
cout<<"après application de l'opérateur \n" ;
z.display() ;
getch() ;
}
Résultat du programme ci-dessus :
Saisir deux chiffres 5 6
Après l'application de l'opérateur
La somme de deux nombres 11
Explication : Le nom de la classe est "sum". Nous avons créé trois objets, deux pour faire la somme et l'autre
pour renvoyer la somme. +" est un opérateur binaire qui opère sur les membres de deux objets et renvoie le
résultat qui est membre d'un objet. Ici, le nombre de paramètres est de 1. La somme est affichée dans la fonction
d'affichage.

Écrire un programme pour surcharger les opérateurs arithmétiques sur les nombres complexes à l'aide
d'une fonction membre.
#include<iostream.h>
classe complexe
{
float real,img ;
public :
complex(){ }
complexe(float x, float y)
{
real=x ;
img=y ;
}
complexe operator+(complexe c) void display() ;
};
complexe complexe::operator+(complexe c)
{
température complexe ;
temp.real=real+c.real ;
temp.img=img+c.img ;
retour temp ;
}
void complex::display()
{
int imag=img ;
Si(img<0)
{
imag=-imag ;
cout<<real<<"-i"<<imag ;
} else cout<<real<<"+i"<<img ;
}
int main()
{
complexe c1,c2,c3 ;
c1=complexe(2,5,3,5) ;
c2=complexe(1,6,2,7) ;
c3=c1+c2 ;
c3.display() ;
retour 0 ;
}
Surcharge des opérateurs binaires à l'aide d'amis

1. Remplacer la déclaration de la fonction membre par la déclaration de la fonction amie dans la classe
friend complex operator+(complex, complex)
2. Redéfinir la fonction de l'opérateur comme suit :
opérateur complexe+(complexe a, complexe b)
{
return complex((a.x+b.x),(a.y+b.y)) ;
}
Ecrire un programme pour surcharger les opérateurs arithmétiques sur les nombres complexes en
utilisant la fonction friend #include<iostream.h>.
classe complexe
{
float real,img ;
public :
complex(){ }
complexe(float x, float y)
{
real=x ;
img=y ;
}
ami opérateur complexe+(complexe) ;
void display() ;
};
opérateur complexe+(complexe c1, complexe c2)
{
température complexe ;
temp.real=c1.real+c2.real ;
temp.img=c1.img+c2.img ;
retour temp ;
}
void complex::display()
{
Si(img<0)
{
img=-img ;
cout<<real<<"-i"<<img ;
}
autre
cout<<real<<"+i"<<img ;
}
int main()
{
complexe c1,c2,c3 ;
c1=complexe(2,5,3,5) ;
c2=complexe(1,6,2,7) ;
c3=c1+c2 ;
c3.display() ;
retour 0 ;
}
UNITÉ -5

Modèles et gestion des exceptions :


Introduction, modèles de classes, modèles de classes avec paramètres multiples, modèles de fonctions,
modèles de fonctions avec paramètres multiples, modèles de fonctions membres. Gestion des
exceptions : Principes de base de la gestion des exceptions, types d'exceptions, mécanisme de gestion
des exceptions, mécanisme de renvoi et de rattrapage, renvoi d'une exception, spécification des
exceptions.

PROGRAMMATION GENERIQUE(Modèles)
La programmation générique est une approche dans laquelle les types génériques sont utilisés comme
paramètres dans les algorithmes afin qu'ils fonctionnent pour une variété de types de données et de structures
de données appropriés.
Un avantage important de la programmation orientée objet est la réutilisation du code qui élimine le
codage redondant. Une caractéristique importante du C++, les modèles, renforce cet avantage de la POO et
apporte une grande flexibilité au langage. Les modèles prennent en charge la programmation générique, ce qui
permet de développer des composants logiciels réutilisables tels que des fonctions, des classes, etc. prenant en
charge différents types de données dans un cadre unique.

Concept des modèles


Introduction
Au lieu d'écrire des fonctions différentes pour les différents types de données, nous pouvons définir des
fonctions communes de type

fonction. Par exemple

int max(int a,int b) ; // Renvoie le maximum de deux entiers float


max(float a,float b) ; // Retourne le maximum de deux flottants char max(char a,char b) ; // Retourne le
maximum de deux caractères (c'est ce qu'on appelle une surcharge de fonction)
Mais au lieu d'écrire trois fonctions différentes comme ci-dessus, le C++ a mis à disposition une fonction
appelée "Templates". À l'aide des modèles, vous pouvez définir une seule fonction commune, comme suit :

T max(T a,T b) ; // T est appelé type de données générique

Les fonctions modèles permettent de créer des abstractions de fonctions/classes en créant le comportement
d'une fonction sans savoir quelles données seront traitées par cette fonction. D'une certaine manière, c'est ce
que l'on appelle les "fonctions génériques ou la programmation".
La fonction de modèle est davantage axée sur la pensée algorithmique que sur un moyen spécifique de type de
données unique. Par exemple, vous pouvez créer une fonction modèle de poussée de pile. Cette fonction push
peut gérer l'opération d'insertion dans une pile de n'importe quel type de données plutôt que de devoir créer
une fonction push pour chaque type de données.
Syntaxe :
template < classe type >
ret_type fun_name(liste de paramètres)
{
--------------//corps de la fonction

} //www.suhritsolutions.com

Caractéristiques des modèles


1. Il élimine les codes redondants
2. Il améliore la réutilisation du code.
3. Il offre une grande flexibilité aux langues
Les modèles sont classés en deux catégories. Ils sont

1 Modèles de fonction
2 Modèles de classe.
Modèles de fonction
Les modèles déclarés pour les fonctions sont appelés modèles de fonction. Un modèle de fonction définit la
manière dont une fonction individuelle peut être construite.
Syntaxe :
template <classe type,.........>
ret _type fun_ name(arguments)
{
-----------------// corps de la fonction
-----------------
}

MODÈLES DE CLASSE
Les modèles déclarés pour les classes sont appelés modèles de classe. Un modèle de classe spécifie la
manière dont les classes individuelles peuvent être construites, de manière similaire à la spécification normale
d'une classe. Ces classes modélisent une classe générique qui prend en charge des opérations similaires pour
différents types de données. Forme générale d'un modèle de classe

template <classe T> classe nom de classe {

…; ….
}

Une classe créée à partir d'un modèle de classe est appelée classe modèle. La syntaxe pour définir un objet
d'une classe modèle est la suivante :

classname<type> objectname(arglist) ;

#include<iostream.h>
#include<conio.h>
template <classe T> classe swap
{
T a,b ;
public :
swap(T x,T y)
{
a=x ;
b=y ;
}
void swapab()
{
T temp ;
temp=a ;
a=b ;
b=temp ;
}
void showdata()
{
cout<<a<<b ;
}
};

void main()
{
int m,n ;
float m1,n1 ;
cout<<"Enter integer values" ;
cin>>m>>n ;
cout<<"Enter floating values" ;
cin>>m1>>n1 ;
swap<int> c1(m,n) ;
swap<float> c2(m1,n1) ;
c1.swapab() ;
c1.showdata() ;
c2.swapab() ;
c2.showdata() ;
}

Modèle de classe avec plusieurs paramètres

Syntaxe :

template <classe T1, classe T2,....> classe nom de classe


{}

#include<iostream.h> template <classe T1,classe T2> classe Test


{
T1 a ;
T2 b ;
public :

Test(T1 x,T2 y)
{ a=x ; b=y ;
}
void show()
{
cout<<a<<b ;
}
};
void main()
{
Test<float,int> test1(1.23,123) ;
Test<int,char> test2(100, "w") ;
test1.show() ;
test2.show() ;
}

MODÈLES DE FONCTIONS
À l'instar des modèles de classe, nous pouvons également définir des modèles de fonction qui seront utilisés
pour créer une famille de fonctions avec différents types d'arguments.

Formulaire général :
template <classe T>
type de retour nom de la fonction (arguments de type T)
{}
#include<iostream.h>
template<classe T>
void swap(T &x, T &y)
{
T temp = x ;
x=y ;
y=temp ;
}
void fun(int m,int n,float a,float b)
{
cout<<m<<n ;
swap(m,n) ;
cout<<m<<n ;
cout<<a<<b ;
swap(a,b) ;
cout<<a<<b ;
}
int main()
{
fun(100,200,11.22,33.44);
retour 0 ;
}
Exemple 2:-
#include < iostream.h >
#include < conio.h >
modèle
T max(T a, T b)
{
si(a>b)
retourner a ;
autre
retour b ;
}
void main( )
{
char ch1,ch2,ch3 ;
cout<<"entrer deux caractères"<< ch2<< ch3 ;
cin>>ch2>>ch3 ;
d=max(ch2,ch3) ;
cout<<"max(ch2,ch3)"<< ch1 ;
int a,b,c ;
cout<<"enter two integers :";
cin>>a>>b ;
c=max(a,b) ;
cout<"max(a,b) :"<< c<< endl ;
float f1,f2,f3 ;
cout<"enter two floats< f1f2 > :";
cin>>f1,f2 ;
f3=max(f1,f2) ;
cout<<"max(f1,f2) :"<< f3 ;
}

de la production :
entrez deux caractères : A,B
max(ch2,ch3):B
entrez deux nombres entiers:20,10
max (a,b) :20
entrez deux flottants :20.5,30.9
max (f1,f2) :30.9

Modèle de fonction avec plusieurs paramètres


Comme pour le modèle de classe, nous pouvons utiliser plusieurs types de données génériques dans la
déclaration de modèle, en utilisant une liste séparée par des virgules, comme indiqué ci-dessous :
template <classe T1, classe T2,.> return-type function-
name(arguments de types T1,T2.) {

}
#include<iostream.h>
#inlcude<string.h>
template<classe T1, classe T2> void display(T1 x,T2 y) {
cout<<x<<y ;
}
int main()
{
display(1999, "EBG") ;
display(12.34,1234) ;
retour 0 ;
}

Gestion des exceptions


Exceptions : Les exceptions sont des anomalies d'exécution ou des conditions inhabituelles qu'un programme
peut rencontrer au cours de son exécution. Les anomalies peuvent inclure des conditions telles que la division
par zéro, l'accès à un tableau en dehors de ses limites ou l'épuisement de la mémoire ou de l'espace disque.
Lorsqu'un programme rencontre une condition d'exception, celle-ci doit être identifiée et traitée.
Les exceptions permettent de transférer le contrôle d'une partie du programme à une autre. La gestion
des exceptions en C++ repose sur trois mots-clés : try, catch et throw.

Types d'exceptions : il existe deux types d'exceptions


1. exceptions synchrones
2. exceptions asynchrones

1) Exceptions synchrones : les erreurs telles que "Indice hors plage" et "dépassement de débit" sont des
exceptions synchrones.
2. les exceptions asynchrones : Les erreurs générées par un événement échappant au contrôle du programme
sont appelées exceptions asynchrones.

L'objectif de la gestion des exceptions est de fournir un moyen de détecter et de signaler une circonstance
exceptionnelle

Mécanisme de gestion des exceptions :


Une exception est censée être levée à l'endroit où une erreur ou une condition anormale est détectée. Le
lancement entraînera l'interruption du déroulement normal du programme, dans le cadre d'une exception levée.
Une exception est lancée de manière programmatique, le programmeur spécifie les conditions de lancement.
Dans les exceptions gérées, l'exécution du programme reprend à un bloc de code désigné, appelé bloc
de capture, qui englobe le point de lancement en termes d'exécution du programme. Le bloc de réception peut
être, et est généralement, situé dans une fonction différente de celle du point de lancement.

La gestion des exceptions en C++ repose sur trois mots-clés : try, catch et throw.
Try est utilisé en préambule d'un bloc d'instructions susceptibles de générer des exceptions. Ce bloc de déclarations est
connu sous le nom de bloc d'essai. Lorsqu'une exception est détectée, elle est levée en utilisant l'instruction throw dans le
bloc try. Le bloc Catch capture l'exception lancée par l'instruction throw dans le bloc try et la traite de manière
appropriée.
#include<iostream>
using namespace std ;
int main()
{
int a,b ;
cout<<"Entrez deux valeurs entières quelconques" ;
cin>>a>>b ;
int x=a-b ;
essayer
{
si(x!=0)
{

cout<"Result(a/x)="<<a/x<<endl ;
}
autre
{ throw x ;
}
}
catch(int ex)
{
cout<"Exception caught:Divide By Zero \n" ;
}
}

MÉCANISME DE PROJECTION
Lorsqu'une exception est détectée, elle peut être levée en utilisant l'instruction throw sous l'une des formes
suivantes
throw(exception) ; throw exception ;

jeter ;
MÉCANISME DE CAPTURE :

Le bloc de capture est le suivant


Catch(data type arg) {
//déclarations pour le traitement
//exceptions
}
Multiples déclarations de capture :
essayer
{
//essayez le bloc
}
catch(data type1 arg)
{
//catch block1
}
catch(data type2 arg)
{
//catch block2
} catch(data typeN arg)
{
//catch blockN
}

• Lorsqu'une exception est déclenchée, le gestionnaire d'exception est recherché dans l'ordre pour
trouver une correspondance appropriée.
• Il est possible que les arguments de plusieurs instructions catch correspondent au type d'une exception.
Dans ce cas, le premier gestionnaire correspondant au type d'exception est exécuté

Écrire un programme pour attraper plusieurs instructions catch


#include<iostream.h>
void test(int x)
{
essayer
{
if(x==1) throw x ;
autre
if(x==0) throw 'x' ;
autre
if(x==-1) throw 1.0 ;
cout<<"end of try block"<<endl ;
}
catch(char c)
{
cout<<"a attrapé un caractère"<<endl ;
}
catch(int m)
{

cout<<"caught an integer"<<endl ;
}
catch(double d)
{

cout<<"caught a double"<<endl ;
}
}
int main()
{
test(1) ;
test(0) ;
test(-1) ;
test(2) ;
retour 0 ;
}

Sortie :
a attrapé un entier
a attrapé un personnage
a pris un double
fin du bloc d'essai

Rattraper toutes les exceptions :

tous les types d'exceptions possibles et peut donc ne pas être en mesure de concevoir des gestionnaires de
capture indépendants pour les attraper. Dans de telles circonstances, nous pouvons forcer une instruction
catch à attraper toutes les exceptions au lieu d'un certain type seulement.

catch(...)
{}

Écrire un programme pour attraper toutes les exceptions


#include<iostream.h>
void test(int x)
{
essayer
{
if(x==0) throw x ;
if(x==0) throw 'x' ;
if(x==-1) throw 1.0 ;
}
catch(...)
{
cout<<"caught exception"<<endl ;
}
}
int main()
{
test(-1) ;
test(0) ;
test(1) ;

retour 0 ;
}

Renvoi d'une exception :

Il est possible de transmettre une exception capturée par un bloc catch à un autre gestionnaire d'exception.
C'est ce que l'on appelle le "Re-throwing".

#include <iostream>
using namespace std ;
void MyHandler()
{ try {
lancer "hello" ;
}
catch (const char*)
{
cout <<"Caught exception inside MyHandler\n" ;
throw ; //rethrow char* out of function
}
}
int main()
{ cout<< "Main start....."<<endl ; try
{
MyHandler() ;
}
catch(const char*)
{
cout <<"Caught exception inside Main\n" ;
}
cout << "Fin principale" ;
retour 0 ;
}

Spécification des exceptions :


La spécification d'une exception limite les fonctions à lancer certaines exceptions spécifiées uniquement avec
l'utilisation de throw(liste d'exceptions) dans l'en-tête de la fonction.
Formulaire général
Type nom_de_la_fonction(liste d'arguments) throw(exceptions -list)
{
Déclarations
try {
déclarations
}

#include <iostream>
using namespace std ;
void test(int x) throw(int,float,char)
{
switch(x)
{
case 1:throw x ;
pause ;
cas 2:jeter 'x' ;
pause ;
case 3:throw double(x) ;
pause ;
case 4:throw float(x) ;
pause ;
}
}
int main()
{
essayer
{
test(4);//test(4) conduit à une terminaison anormale
}

catch(int i)
{
cout <<"Caught int type exception\n" ;
}
catch(float f)
{
cout <<"Caught float type exception\n" ;
}
catch(char c)
{
cout <<"Caught char type exception\n" ;
}
catch(double i)
{
cout <<"Caught Double type exception\n" ;
}

retour 0 ;
}

Vous aimerez peut-être aussi