Apprendre à créer des projets avec le langage C++
Apprendre à créer des projets avec le langage C++
…
Attribut et État d’un objet
Un objet est caractérisé par:
– Les services proposés: se sont les méthodes de l‟objet
– ses champs, son État et son nom. les champs
– Information qui qualifie l‟objet qui le contient;
– Peut être une constante.
État
– Valeurs instantanées de tous les attributs d‟un objet
– Évolue au cours du temps
– Dépend de l‟histoire de l‟objet solde : 10
DEBITAUTORISE : 1
compte001 : CompteBancaire
Identité d’objet champs variable
champs constant
Comportement d’un objet
Le comportement d‟un objet décrit les actions et les réactions d‟un objet
– Se sont les services offerts par un objet
Service = opération = méthode
Un comportement est déclenché par un message (invocation de service) d‟un objet par un autre objet.
compte001: CompteBancaire
dupont : Client
consulter () consulter( ) est un service offert par compte001 à dupont
Les objets sont rattachés à leur classe odie felix grosminet titi monTéléphone
Être vivant Chose
Animal Personne Interactif « Inerte »
Chien Chat Oiseau Téléphone Compte Voiture Livre
Portable CompteCourant CompteEpargne
On classe les objets par famille en faisant abstraction de quelques différences. On élabore ainsi une définition théorique de ce que doit être un objet de cette famille ou de cette classe.
les familles d’objets partagent un ensemble d’attributs et de services, en fonction de leur position dans l’arborescence.
Les classes
Spécification
Une classe est une description d’une famille d’objets, qui ont :
Mêmes attributs
Même méthodes
Une classe est une moule d‟un ensemble d‟objets qui partagent une structure commune (les attributs) et un comportement commun (les méthodes).
Une classe est une collection de champs (variables membres sans valeurs), de fonctions membres (les méthodes), qui leur sont attachées et qui définissent le comportement d'un objet.
Une classe est une entité qui permet de regrouper un ensemble de données et les méthodes qui leurs sont attachées.
Une classe correspond aussi a un type de donnée comme int, double, elle correspond au type des objets qui lui sont liés.
Classe CompteBancaire
Attributs
Opérations
….
La classe est structurée en 3 partie (les modes d‟accès):
La partie publique: contient les déclarations visibles à tout utilisateur de cette classe.
La partie protégée: contient les déclarations visibles uniquement par les classes héritant de la classe de base.
La partie privée: contient les déclarations invisibles à toute autre classe différente de la classe de base.
Instance
CompteBancaire
Chaque objet appartient à une classe
On dit que:
– obj1 est un objet de la classe X
– ou
– Obj1 est une instance de la classe X
compte001 : CompteBancaire Instance ou objet classe
solde : 1000
numCompte: 1234
instanciation
Notions importantes en P.O.O
Encapsulation des données.
– Ceci signifie qu'il n'est pas possible pour l'utilisateur d‘un objet, d'accéder directement aux données (les modes d’accès protected et private).
– L’utilisateur doit passer par des méthodes spécifiques écrites par le concepteur de l'objet, et qui servent d'interface entre l'objet et ses utilisateurs.
– L'intérêt de cette technique est évident. L'utilisateur ne peut pas intervenir directement sur les données d’un objet, ce qui diminue les risques d'erreur, ce dernier devenant une "boîte noire".
– En général cela permet de protéger les variables membres contre des modifications incohérentes
Héritage.
– L’héritage permet la définition d'une nouvelle classe à partir d'une classe existante.
– Il est alors possible de lui adjoindre de nouvelles données, de nouvelles fonctions membres (méthodes) pour la spécialiser.
Exemple d’héritage
Les spécifications C++
Une instruction élémentaire est une expression terminée par le caractère ; (point virgule)
– A = B; if (A == B) C = A +B;
Un bloc est une suite d'instructions élémentaires délimitées par des accolades { et }
Un bloc peut contenir un ou plusieurs blocs inclus
Le langage C++ permet d'ajouter des commentaires dans les programmes.
– // permet d‟ignorer tout jusqu'à la fin d‟une ligne
// c‟est une ligne de commentaire
– Pour un bloc de ligne, on utilise Le symbole /* ... */ qui permet de mettre en commentaire le bloc qui y inclus
/*
ligne1 de commentaire…
ligne n de commentaire
*/
Spécifications: Définitions
Identificateur:
– nom formé de lettres et de chiffres, débutant par une lettre ou le _ considéré comme une lettre. (en pratique, on utilise moins de 31 caract.)
Variable:
– identificateur qui sert de nom à une région de la mémoire.
Type:
– attribut qui détermine les dimensions de l'espace mémoire (d'une variable par exemple) et la façon d'interpréter les 1 et 0.
Une variable possède un nom, un type, une taille et une valeur
– Exemple: int longueur = 10;
– Déclaration de la variable Longueur dont le nom est longueur, de taille 4 octet, de type int et de valeur égale à 10.
Les spécifications C++
Les types numérique (les types primitifs)
Nombre entier Nombre réels char short int long float double long double (unsigned)
Spécification C++
La taille des types primitifs:
char: 1 octet
short: 2 octet
int: 4 octet
long: 4 octet
float: 4 octet
double: 8 octet
long double: 8 octet
Opération en C++:
Addition: +
Soustraction: –
Multiplication: *
Division: /
Modulo: %
Spécification C++
Opérateurs relationnels
>, <, >=, <=
Opérateurs d‟égalité == ,(a==b a est égale à b) != ,(a != b a est différent de b)
Opérateur d‟affectation = ,(c = a+b c reçoit la valeur de la somme de a et b)
Les spécifications C++
Pour effectuer les entrées/sorties (flux) dans les programmes, on utilise les fonctions
– cout (pour afficher à l'écran des caractères)
– cin (pour lire sur le clavier: entrer des valeurs ou caractère)
Remarques:
– il faut inclure le fichier <iostream.h> au début du programme pour pouvoir utiliser les entrées/sorties
– L'opérateur d‟insertion << permet d'envoyer des valeurs dans un flot de sortie
– L‟opérateur d‟extraction >> permet d'extraire des valeurs d'un flot d'entrée.
Exemple
#include<iostream.h>
void main(){
int a, b, c;
cout<< “Entrer la valeur de a“<< endl;
cin >> a;
cout<< “Entrer la valeur de b“<< endl;
cin >>b;
if (a >b) c = a + b;
if (a == b) c = a + 1;
if (a < b) c = a – b;
cout <<“la valeur de c est: “ << c<< endl;
}
notez l'absence de l'opérateur & dans la syntaxe du cin. Ce dernier n'a pas besoin de connaître l'adresse de la variable à lire.
Les spécifications C++
Les manipulateurs sont des éléments qui modifient la façon dont les éléments sont lus ou écrits dans le flot.
Les principaux manipulateurs sont :
dec lecture/écriture d'un entier en décimal
oct lecture/écriture d'un entier en octal
hex lecture/écriture d'un entier en hexadécimal
endl insère un saut de ligne et vide les tampons
setw(int n) affichage de n caractères
setprecision(int n) affichage de la valeur avec n chiffres avec éventuellement un arrondi de la valeur
setfill(char) définit le caractère de remplissage flush vide les tampons après écriture
Les spécifications C++
Exemple :
#include <iostream.h>
#include <iomanip.h>
void main( ) {
int i=1234;
float p=12.3456;
cout << "|" << setw(8) << setfill('*') << hex
<< i << "|" <<endl;
Cout<< "|" << setw(6) << setprecision(4) <<
p << "|" << endl;
}
/*-- résultat de l'exécution -------------------
|*****4d2|
|*12.35|
------------------------------------------------*/
Spécification C++
Structure de séléction: if [/else]
– if ( expression ) instruction1 [else instruction2]
La valeur de l'expression est évaluée et, si elle est vraie, instruction1 est exécutée sinon c'est instruction2 qui est exécutée (si elle existe).
La clause else peut être omise et se rapporte toujours au dernier if visible.
Structure de répétition: while
Permet de spécifier q‟une action sera répétée tant que le résultat
d‟une expression reste vraie ou non nul
while(expression){
Instruction ou bloc d’instruction
}
Structure de répétion: do .. While
Idem que while
do{
instruction ou bloc d'instructions
}
while ( expression);
#include <iostream.h>
void main() {
int a, b, compteur, i=0;
cout << " valeur de a " <<endl;
cin >> a;
cout << " valeur de b "<<endl;
cin >> b;
if(a > b) compteur = a +1;
else compteur = b+1;
while(compteur < (2*b)) compteur = compteur +1;
while(i != 10) {
i = i +1;
cout << " maintenant la valeur de i est égale à « <<i<<endl;
}
cout << " la valeur du compteur est : " << compteur<< endl;
do {
compteur += i;
++i;
} while (i <= 20);
cout << " la valeur du compteur est : " << compteur<< endl;
}
La structure de sélection multiple switch:
– permet un choix multiple (plusieurs if else) en fonction de l'évaluation d'une expression.
switch ( expression1 ) {
case e1 : instruction1 ...
case e2 : instruction2 ...
...
case en : instructionn ...
[default : instruction_default ...]
}
Description :
– expression1 doit donner pour résultat une valeur de type int ou char.
– e1, e2, e3 ... sont des expressions constantes qui doivent être un entier de type int ou char.
– La valeur de expression1 est recherchée successivement parmi les valeurs des différentes constantes e1, e2, e3.
En cas d'égalité les instructions (facultatives) correspondantes sont exécutées jusqu'à une instruction break ou jusqu'à la fin du bloc du switch (et ceci indépendamment des autres conditions case).
S'il n'y a pas de valeur correspondante, on exécute les instructions du cas default (s'il existe).
Spécification C++
void main(){
char car;
int somme =0;
cin >>car;
switch (car) {
case 'a' :
case 'A' :
case 'e' :
case 'E' : somme++; break;
case „x' : somme--; break;
default : somme = 10;
}
cout << " valeur de somme est égale à" <<somme<<endl;
}
Remarque:
– L'instruction break provoque le passage à l'instruction qui suit immédiatement le corps de la boucle while, do-while, for ou switch. (on sort complétement de la boucle)
Spécification C++
L'opérateur conditionnel ?:
– Il permet d'écrire des expressions dont le résultat est fonction de certaines conditions.
Syntaxe : ( expression ) ? expression1 : expression2 ;
Si expression est vrai, le résultat est expression1 sinon le résultat est expression2.
expression1 et expression2 doivent être du même type.
Exemple :
n = ( a < 0 ) ? -a : a ;
n contient la valeur absolue de a.
<=> if (a<0) n=-a ; else n =a;
Spécification C++
Opérateurs d‟affectation: ils permettent de simplifier les expression d‟affectation
+= ,(a += b <-> a=a+b)
-= ,(a -= b <-> a=a-b)
*= ,(a *= b <-> a=a*b)
/= ,(a /= b <-> a=a/b)
%= ,(a %= b <-> a=a%b)
Opérateur d‟incrémentation et de décrémentation:
– ++: opérateur pré-incrémentation
++a : incrémenter a de 1, puis utiliser la nouvelle valeur de a dans l‟expression où a réside
– ++: opérateur post-incrémentation a++ : utiliser la valeur courante de a dans l‟expression où a réside, puis incrémenter a de 1
Spécification C++
– --: opérateur pré-décrémentation
--a : décrémenter a de 1, puis utiliser la nouvelle valeur de a dans l‟expression où a réside
– --: opérateur post-décrémentation
a-- : utiliser la valeur courante de a dans l‟expression où a réside, puis décrémenter a de 1
Les spécifications C++
#include <iostream.h>
void main() {
int a=5, b=10, c, d;
a +=b/2;
++b;
c =b+a;
cout << " valeur de c " << c <<endl;
b %=a;
cout << " valeur de b "<< b <<endl;
}
Les spécifications C++
Structure de répétition: for
Syntaxe :
for ( [expression1] ; [expression2] ; [expression3] ){ instruction ou bloc d'instructions
}
Description :
- instruction1 est répétée tant que la valeur de expression2 est vraie.
- expression1 sert à initialiser les variables de la boucle.
Exemple:
int somme;
for (i=0; i<10; i++) somme += i*i;
Spécification C++
L'opérateur de taille:
– L'opérateur sizeof est utilisé pour déterminer la taille (en octets) d'une variable ou d'un type.
Syntaxe :
– sizeof(variable) ou sizeof variable ou sizeof(type)
Exemple:
int a=12; double b=14.4; char c=„M‟;
cout<<“taille de a est:“<<sizeof(a)<<endl;
cout<<“taille de b est:“<<sizeof(b)<<endl;
cout<<“taille de c est:“<<sizeof(c)<<endl;
cout<<“taille du string hello est:“<<sizeof(“hello”)<<endl;
Il faut inclure la bibliothèque (ou le fichier header :
iostream.h):
Spécification C++
C++ fournit aussi le type bool dont les valeurs sont true ou false
– bool var;
Var est une variable de type bool
var est égale à true ou false
Les expressions booléennes
– Se sont des expressions de type bool
– && réalise le "ET booléen" entre 2 expressions. Retourne true si les 2 expressions valent true, false sinon.
– || réalise le "OU booléen" entre 2 expressions. Retourne vrai si l'une ou l'autre (ou les deux), des 2 expressions valent true, false sinon.
exemple:
– (a >= 5 && a <= 10)
retourne true si a est compris entre 5 et 10 sinon false.
– a > 5 || b == 0 retourne true si a est supérieur à 5 ou si b est égal à 0.
l'expression b == 0 ne sera pas évaluée si a est supérieur à 5 (évaluation courte).
Les spécifications C++
En C++, On peut explicitement demander une conversion dans un type désiré.
– Cette opération s'appelle: casting ou transtypage.
– Une expression précédée par un nom de type entre ( ) (parenthèses) provoque la conversion de celle ci dans le type désiré.
int i;
double d=2.55;
i=(int)d; // conversion du double d en int
cout <<“valeur de i est: “<<i<<endl;
Les spécifications C++
DEFINITION DE VARIABLES
– En C++, on peut déclarer les variables ou fonctions n'importe où dans le code.
– La portée de telles variables va de l'endroit de la déclaration jusqu'à la fin du bloc courant.
– Ceci permet :
– de définir une variable aussi près que possible de son utilisation afin d'améliorer la lisibilité.
– C'est particulièrement utile pour des grosses fonctions ayant beaucoup de variables locales.
– d'initialiser, une variable ou une constante, avec une valeur obtenue par calcul ou par saisie, dans
n‟importe quel endroit du code.
Les spécifications C++
Exemple :
#include <iostream.h>
void main() {
int i=0; // définition d'une variable
i++; // instruction
int j=i; // définition d'une autre variable
j++; // instruction
int somme(int n1, int n2); // déclaration d'une fonction
cout <<i << “ “<<j<< “ “<<somme(i, j)<<endl;
cin >> i;
const int k = i; // définition d'une constante initialisée
// avec la valeur saisie
Cout << “valeur de k est: “<< k <<endl;
}
créer la fonction somme(int, int) ; // ???
Les spécifications C++
VARIABLE DE BOUCLE
- On peut déclarer une variable de boucle directement dans l'instruction for.
- Ceci permet de n'utiliser cette variable que dans le bloc de la boucle.
Exemple :
#include <iostream.h>
void main() {
for(int i=0; i<10; i++) cout << i << endl;
// i n'est pas utilisable à l'extérieur du bloc for
}
Les spécifications C++
VISIBILITE DES VARIABLES
L'opérateur de résolution de portée :: permet d'accéder aux variables globales plutôt qu'aux variables locales.
#include <iostream.h>
int i = 11; // variable globale
void main() {
int i = 34;
{ int i = 23;
::i = ::i + 1;
cout << ::i << " " << i << endl;
}
cout << ::i << " " << i << endl;
}
/*-- résultat de l'exécution ------------------
12 23
12 34
Remarque:
– En fait, on utilise beaucoup cet opérateur pour définir hors d'une classe les fonctions membres ou pour accéder à un identificateur dans un espace de noms.
– L'utilisation abusive de cette technique n'est pas une bonne pratique de programmation (lisibilité). Il est préférable de donner des noms différents plutôt que de réutiliser les mêmes noms.
Les spécifications C++
LES TYPES COMPOSES
– En C++, comme en langage C, le programmeur peut définir
des nouveaux types en définissant par exemple des struct ,
enum ou union.
– Mais contrairement au langage C, l'utilisation de typedef n'est plus obligatoire pour renommer un type.
Exemple :
struct FICHE { // définition du type FICHE
char *nom, *prenom; int age;
};
– En C, il faut ajouter la ligne : typedef struct FICHE; pour construire un synonyme du type Fiche typedef struct fiche fiche; permet de construire un synonyme de la structure fiche, en C,
– par contre, on écrit simplement fiche, en C++, pour créer des variables de type fiche.
FICHE adherent, *liste; //déclaration de deux variables de type Fiche variables références
En plus des variables normales et des pointeurs, le C++ offre les variables références.
Une variable référence permet de créer une variable qui est un "synonyme" d'une autre,
Une variable et sa référence désignent le même emplacement mémoire
Donc, une modification de l'une affectera le contenu de l'autre.
int i, *ptr;
int &ir = i; // ir est une référence à i ou synonyme de i
i=1;
cout << "i= " << i << " ir= " << ir << “adresse de
i: ” <<&i << “adresse de ir: ” << &ir <<endl;
// affichage de : i= 1 ir= 1 adresse de i: 15F adresse de ir 15F
Une fois une référence est déclarée et initialisée, on ne peut la modifier: ir est une référence sur i et non sur autre variable variables références
ir=2;
cout << "i= " << i << " ir= " << ir << endl;
// affichage de : i= 2 ir= 2
ptr = &ir;
*ptr = 3;
cout << "i= " << i << " ir= " << ir << endl;
// affichage de : i= 3 ir= 3
Attention
int n=5, &pp = n;
int &p = 3
// initialisation d‟une référence par une constante: incorrecte
float x = 5;
pp = x;
// donc affectation de la valeur de int(x) à pp et non changement de référence de n à x pour pp variables références
Une variable référence doit obligatoirement être initialisée et le type de l'objet initial doit être le même que l'objet référence.
Après l‟initialisation, on ne peut pas changer la
valeur d‟une référence (c.a.d: la relation entre référence et la variable référée et fixée une fois pour toute).
Différences entre pointeur et une référence:
1- La définition d’un pointeur est une création de variable, avec un emplacement mémoire propre, alors que la définition d’une référence ne crée qu’un synonyme et donc pas réservation de mémoire.
2- Un pointeur étant une variable, il est possible d’en modifier le contenu, et le même pointeur peut permettre d’accéder successivement à des variables différentes.
Par contre, L’association entre une référence et la variable qu’elle désigne est fixée définitivement lors de l’initialisation de celle-ci.
variables références
Intérêts:
– passage des paramètres par référence: dans le cas des fonctions
– utilisation d'une fonction en lvalue: en utilisant surtout la surdéfinition d’opérateur (l’opérateur &), on récupère le retour de la fonction qui retourne une référence "donc une adresse" du résultat.
Exemple :
int t[20];
int & nIeme(int i) {
return t[i];
}
void main() {
nIeme(0) = 123; // utilisation de la fct nIeme comme une lvalue
nIeme(1) = 456;
cout << t[0] << " " << ++nIeme(1);
}
// -- résultat de l'exécution -----------
// 123 457
variables références
En C, on aurait pu écrire le programme
suivant :
int * nIeme(int i) {
return &t[i];
}
void main() {
*nIeme(0) = 123;
*nIeme(1) = 456;
cout << t[0] << “ “ <<++(*nIeme(1)) <<
endl;
}
Allocation dynamique de la mémoire
Le C++ met à la disposition du programmeur deux opérateurs new et delete (comme malloc et free en C mais en plus simple)
o L'opérateur new permet d’allouer de la mémoire qu'on lui demande et l'initialise (permet de créer des tableaux dynamiques).
o Il retourne l'adresse de début de la zone mémoire allouée.
int *ptr1, *ptr2, *ptr3;
Allocation dynamique d'un entier
– ptr1 = new int; // ptr1 est un pointeur qui pointe vers un int
Allocation dynamique d'un tableau de 10 réels
– ptr2 = new double [10];
Allocation d'un entier avec initialisation
– ptr3 = new int(10);
Allocation dynamique de la mémoire
Exemple de code:
int taille;
int *A;
cout << "entrer la taille de votre tableau A:" << endl;
– cin >> taille;
on construit d‟une façon dynamique un tableau avec la donnée taille, on a pas à spécifier que taille est une constante pour construit notre tableau.
– A = new int[taille];
A est un pointeur qui pointe vers l‟adresse du premier élément du tableau crée dynamiquement par l‟opérateur new, dont la dimension est taille.
Allocation dynamique de la mémoire
struct date {int jour, mois, an; };
date *ptr4, *ptr5, *ptr6, d = {25, 4, 1952}; allocation dynamique d'une structure
– ptr4 = new date; allocation dynamique d'un tableau de structure
– ptr5 = new date[10]; allocation dynamique d'une structure avec initialisation.
– ptr4 = new date(d);
Allocation dynamique de la mémoire
En cas d'erreur d'allocation par new, un message
d‟erreur est affiché ( exception bad_alloc)
L‟opérateur delete permet de libérer la mémoire qui est allouée par l‟opérateur new
Exemple
– char *ptr = new char [10];
// création d‟un tableau dynamique de 10 char
Initialisation de la dimension du tableau via
ptr peut être n‟importe où dans le programme, ce qui n‟était pas le cas des tableaux
– for(int i=0, i < 10; i++) ptr[i] = „A‟;
– delete[] ptr;
//la place mémoire pointée par ptr est libérée
Exemple
struct date {int jour, mois, an; };
void main(){
date *ptr4, *ptr5, d = {25, 4, 1952};
ptr4 = new date;
ptr5 = new date[10];
ptr4->jour = 22;
ptr4->mois = 04;
ptr4->an = 2005;
cout << "date de naissance par ptr4 est: "<<ptr4->jour<<"/"<<ptr4-
>mois<< "/"<<ptr4->an<<endl;
ptr4 = new date(d);
cout << "date de naissance par ptr4 est: "<<ptr4->jour<<"/"<<ptr4-
>mois<< "/"<<ptr4->an<<endl;
ptr5[0].jour = 01;
ptr5[0].mois = 02;
ptr5[0].an = 1999;
cout << "date de naissance par ptr5[0] est:
"<<ptr5[0].jour<<"/"<<ptr5[0].mois<< "/"<<ptr5[0].an<<endl;
delete ptr4;
delete[] ptr5;
}
Les fonctions
Le langage C++ impose au programmeur de déclarer le nombre et le type des arguments de la fonction.
Ces déclarations sont identiques aux prototypes de fonctions de la norme CANSI.