La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Faculté de Génie Informatique UNC Le Langage C++

Présentations similaires


Présentation au sujet: "Faculté de Génie Informatique UNC Le Langage C++"— Transcription de la présentation:

1 Faculté de Génie Informatique UNC Le Langage C++
Mr. Mamadou Sanou BALDE Ingénieur d’Etat en Génie Informatique

2 Sommaire Introduction générale Les entrées sorties Les Fonctions
La Programmation orientée Objet La surcharge des opérateurs L’héritage Les Template ou modèles (la généricité) Les Conteneurs STL La gestion des exceptions.

3 Historique du c++ Définition:
Le langage C++ est une « amélioration » du langage C  ( M.Ritchie et B.W.Kernighan au début des années 70) . Bjarne Stroustrup, un ingénieur considéré comme l'inventeur du C++, a en effet décidé d'ajouter au langage C les propriétés de l'approche orientée objet. Ainsi, vers la fin des années 80 un nouveau langage, baptisé C with classes (traduisez « C avec des classes »), apparaît. Celui-ci a ensuite été renommé en C++, clin d'œil au symbole d'incrémentation ++ du langage C, afin de signaler qu'il s'agit d'un langage C amélioré (langage C+1).

4 Les améliorations du C++
Le C++ reprend la quasi-intégralité des concepts présents dans le langage C, si bien que les programmes écrits en langage C fonctionnent avec un compilateur C++. En réalité le langage C++ est un sur ensemble du C, il y ajoute, entre autres, des fonctionnalités objet : Encapsulation Héritage Polymorphisme ainsi qu'un ensemble de nouvelles fonctionnalités, parmi lesquelles : les arguments par défaut Le passage par référence Les templates (Les fonctions génériques) la surcharge de fonctions les fonctions inline , les fonctions amies.

5 Le fichier source Le fichier source d'un programme écrit en langage C++ est un simple fichier texte dont l'extension est par convention .CPP. Lorsque le programme est prêt à être « essayé », il s'agit de le compiler (le traduire en langage machine) à l'aide d'un compilateur. Les principaux I DE permettant le développement d'applications en langage C++ sont : Borland C++ Borland C++ Builder Microsoft Visual C++ Dev C++

6 Aspect d’un programme C++
Les mêmes types que le c, les mêmes structure de contrôle. Les mêmes opérateurs que le C.

7 Les Entrées Sorties La bibliothèque iostream permet d’accéder aux fonction d’entrée et sortie. #include <iostream> #include <string> using namespace std; int main() { cout << "Quel est votre prenom ?" << endl; string nomUtilisateur; cin>> nomUtilisateur; cout << "Vous vous appelez " << nomUtilisateur << endl } "

8 Les Entrées Sorties Toutes les fonctions standards du C++ sont regroupées dans le namespace STD using namespace std; cout << "Hello" << endl; Sans using namespace std; std::cout << "Hello" << std::endl; Il est possible de définir ses propres namespaces namespace test { int i; int j;} using namespace test::i; " Namespace ce sont des espaces de stockages des variables qu’on peut directement utiliser dans les programmes. Use "using namespace std" at the top of each file, outside of any function - this will make the standard library facilities available throughout the program. We use this approach at CUED for smaller teaching programs.

9 Fichiers : lecture / ecriture
Ouverture en lecture: ifstream #include <iostream> #include <fstream> using namespace std; int main() { ifstream fichier("test.txt", ios::in); // on ouvre le fichier en lecture if(fichier) // si l'ouverture a réussi { // instructions fichier.close(); // on ferme le fichier } else // sinon cerr << "Impossible d'ouvrir le fichier !" << endl; return 0; } "

10 Fichiers : lecture / ecriture
Ouverture en écriture : ofstream ios::out (pour output) : spécifie qu'on ouvre le fichier en écriture. Obligatoire - mais par défaut - quand on utilise un objet ofstream ; ios::app (pour append = ajouter à la suite) : lorsqu'on ouvre le fichier en écriture, on se trouve à la fin pour écrire des données à la suite du fichier (sans effacer le contenu, s'il y en a un). Avec ce mode d'ouverture, à chaque écriture, on est placé à la fin du fichier, même si on se déplace dans celui-ci avant (on verra comment se déplacer un peu plus tard ); ios::trunc (pour truncate = tronquer) : lorsqu'on ouvre le fichier en écriture, spécifie qu'il doit être effacé s'il existe déjà, pour laisser un fichier vide ; ios::ate (pour at end) : ouvre le fichier en écriture et positionne le curseur à la fin de celui-ci. La différence avec ios::app est que si on se repositionne dans le fichier, l'écriture ne se fera pas forcément à la fin du fichier, contrairement à ios::app. "

11 Fichiers : lecture / ecriture
#Ouverture d’un fichier en ecriture #include <iostream> #include <fstream> using namespace std; i nt main() { ofstream fichier("test.txt", ios::out | ios::trunc); //déclaration du flux et ouverture du fichier i f(fichier) // si l'ouverture a réussi { // instructions fichier.close(); // on referme le fichier } else // sinon cerr << "Erreur à l'ouverture !" << endl; return 0; } "

12 Fichiers : lecture / ecriture
#Ouverture d’un fichier en lecture et ecriture En utilisant fstream, on ouvre en lecture et en écriture un fichier. Le fonctionnement est le même que pour ifstream ou ofstream. Le prototype pour utiliser cette méthode d'ouverture est : fstream flux("fichier.extention", ios::in | ios::out | [ios::trunc | ios::ate]);. getline(flux, chaineDeCaractères) : pour lire une ligne complète ; flux.get(caractère) : pour lire un caractère ; flux >> variable : pour récupérer à partir du fichier jusqu'à un délimiteur (espace, saut à la ligne, ...). flux << élémentQuelconque : écrit dans le fichier un élément quelconque (string, int, ...) ; flux.put(caractère) : écrit un seul caractère dans le fichier. "

13 #Ouverture d’un fichier en lecture et ecriture
En utilisant fstream, on ouvre en lecture et en écriture un fichier. Le fonctionnement est le même que pour ifstream ou ofstream. Le prototype pour utiliser cette méthode d'ouverture est : fstream flux("fichier.extention", ios::in | ios::out | [ios::trunc | ios::ate]);. getline(flux, chaineDeCaractères) : pour lire une ligne complète ; flux.get(caractère) : pour lire un caractère ; flux >> variable : pour récupérer à partir du fichier jusqu'à un délimiteur (espace, saut à la ligne, ...). flux << élémentQuelconque : écrit dans le fichier un élément quelconque (string, int, ...) ; flux.put(caractère) : écrit un seul caractère dans le fichier. "

14 Fichiers : Fonctions utiles.
Quelques Fonctions Utiles flux.eof() pour savoir si le "curseur virtuel" a atteint la fin du fichier ; flux.ignore(nbCaractere, caractereDeFin) pour ignorer nbCaractere lu OU ignorer tout jusqu'à ce que caractereDeFin est rencontré ; flux.clear() pour remettre les flags d'état à leur état d'origine ; flux.fail() pour tester si l'ouverture du flux s'est bien déroulée. Très utile pour vérifier qu'un fichier existe. Retourne false quand le fichier n’existe pas. "

15 Travaux Pratiques TP1 : premier programme C++ , lecture / écriture dans un fichier. "

16 Les Fonctions : Paramètre par défaut
En déclarant une fonction , nous pouvons spécifier les valeurs par défaut pour chacun des derniers paramètres. Ces valeurs seront utilisées lorsque l’utilisateur ne les renseigne pas en appelant la fonction. #include <iostream> using namespace std; int divide (int a, int b=2) // { int r; r=a/b; return (r); } int main () { cout << divide (12); cout << endl; cout << divide (20,4); return 0; } "

17 Les Fonctions en ligne Le mot clé inline indique au compilateur que l’on désire que le compilateur remplace l’appel de la fonction par le code correspondant Normalement, un appel de fonction est une rupture de séquence : à l'endroit où un appel figure, la machine cesse d'exécuter séquentiellement les instructions en cours ; les arguments de l'appel sont disposés sur la pile d'exécution, et l'exécution continue ailleurs, là où se trouve le code de la fonction. Une fonction en ligne est le contraire de cela : là où l'appel d'une telle fonction apparait il n'y a pas de rupture de séquence. Au lieu de cela, le compilateur remplace l'appel de la fonction par le corps de celle-ci, en mettant les arguments affectifs à la place des arguments formels. Cela se fait dans un but d'efficacité Mais il est clair qu'un tel traitement ne peut convenir qu'à des fonctions fréquemment appelées de petite taille (sinon le code compilé risque de devenir démesurément volumineux) et rapides (si une fonction effectue une opération lente, le gain de temps obtenu en supprimant l'appel est négligeable). " elles ne peuvent pas être récursives ; • elles ne sont pas instanciées, donc on ne peut pas faire de pointeur sur une fonction inline. Si l’une de ces deux conditions n’est pas vérifiée pour une fonction, le compilateur l’implémentera classiquement (elle ne sera donc pas inline). Enfin, du fait que les fonctions inline sont insérées telles quelles aux endroits où elles sont appelées, il est nécessaire qu’elles soient complètement définies avant leur appel. Cela signifie que, contrairement aux fonctions classiques, il n’est pas possible de se contenter de les déclarer pour les appeler, et de fournir leur définition dans un fichier séparé. Dans ce cas en effet, le compilateur générerait des références externes sur ces fonctions, et n’insérerait pas leur code. Ces références ne seraient pas résolues à l’édition de lien, car il ne génère également pas les fonctions inline, puisqu’elles sont supposées être insérées sur place lorsqu’on les utilise. Les notions de compilation dans des fichiers séparés et d’édition de liens seront présentées en détail dans le Chapitre 6.

18 Les Fonctions en ligne Les fonctions en ligne sont comme les macros
inline int abs(int x) { return x >= 0 ? x : -x; } L’appel se fait comme les autres focntions.

19 Les Fonctions Passage par références
A coté des pointeurs, les références sont une autre manière de manipuler les adresses des objets placés dans la mémoire. Une référence est un pointeur gérée de manière interne par la machine. Si T est un type de donnée, le type référence sur T se note T&. Exemple : int i; int & r = i; // r est une référence sur i. Une valeur de type référence est une adresse mais, hormis lors de son initialisation, toute opération effectuée sur la référence agit sur l'objet référencé non sur l'adresse. Il en découle qu'il est obligatoire d'initialiser une référence lors de sa création ; après c'est trop tard. r = j; // ceci ne transforme pas r en une référence sur j mais copie la valeur de j dans r

20 Les Fonctions Passage par références
L'utilité principale des références est de permettre de donner aux fonctions des paramètres modifiables, sans utiliser explicitement les pointeurs. Exemple : void permuter(int & a, int & b) { int w = a; a = b; b = w; } Lors d'un appel de cette fonction, comme permuter(t[i], u); Cette fonction permute réellement les arguments des deux fonctions

21 Surcharge des noms de fonctions
La signature d'une fonction est la suite des types de ses arguments formels . La surcharge des noms des fonctions consiste en ceci : en C++ des fonctions différentes peuvent avoir le même nom, à la condition que leurs signatures soient assez différentes pour que, lors de chaque appel, le nombre et les types des arguments effectifs permettent de choisir sans ambigüité la fonction à appeler. Exemple : int puissance(int x, int n) { calcul de x puisance n avec x et n entiers } double puissance(double x, int n) { calcul de x puissance n avec x flottant et n entier } double puissance(double x, double y) { calcul de x puissance y avec x et y flottants }

22 Les Fonctions Allocation dynamique de la mémoire
Des différences entre C et C++ existent aussi au niveau de l'allocation et de la restitution dynamique de la mémoire. Les fonctions malloc et free de la bibliothèque standard C sont disponibles en C++. Mais il est fortement conseilllé de leur préférer les opérateurs new et delete. La raison principale est la suivante : les objets créés à l'aide de new sont initialisés à l'aide des constructeurs correspondants, ce que ne fait pas malloc. De même, les objets liberés en utilisant delete sont finalisé es en utilisant le destructeur de la classe correspondante, contrairement à ce que fait free. Machin *ptr = new Machin; // un objet Machin int *tab = new int[n]; // un tableau de n int delete p; dans le cas d'un objet qui n'est pas un tableau, et delete [] p; si ce que p pointe est un tableau.

23 Les Fonctions Passage par références
TP 2 : les fonctions

24 Classes et Objets C'est un concept servant a représenter, modéliser toute entité décrite selon ses propriétés et son comportement. Ce comportement s'observe via les interactions que le monde extérieur peut avoir avec cette entité. Les interactions sont sollicitées a travers les opérations de l'objet. C'est un concept oriente objet destine a modéliser formellement des objets d'un certain type d'entité. La classe décrit les propriétés et les opérations des objets du type d'entité qu'il représente. La classe est un type et l’objet est une instance de la classe. C'est un concept servant a representer, modeliser toute entite decrite selon ses proprietes et son comportement. Ce comportement s'observe via les interactions que le monde exterieur peut avoir avec cette entite. Les interactions sont sollicitees a travers les operations de l'objet. C'est un concept oriente objet destine a modeliser formellement des objets d'un certain type d'entite. La classe decrit les proprietes et les operations des objets du type d'entite qu'il represente.

25 Classes et Objets Un objet est constitué par l'association d'une certaine quantité de mémoire, organisée en champs, et d'un ensemble de fonctions, destinées principalement à la consultation et la modification des valeurs de ces champs. La définition d'un type objet s'appelle une classe. D'un point de vue syntaxique, cela ressemble beaucoup à une définition de structure : le mot réservé class remplace le mot struct, certains champs de la classe sont des fonctions. class Point { public: void afficher() { cout << '(' << x << ',' << y << ')'; } void placer(int a, int b) { validation des valeurs de a et b; x = a; y = b; private: int x, y; }; La classe est un type et l’objet est une instance de la classe. C'est un concept servant a representer, modeliser toute entite decrite selon ses proprietes et son comportement. Ce comportement s'observe via les interactions que le monde exterieur peut avoir avec cette entite. Les interactions sont sollicitees a travers les operations de l'objet. C'est un concept oriente objet destine a modeliser formellement des objets d'un certain type d'entite. La classe decrit les proprietes et les operations des objets du type d'entite qu'il represente.

26 Classes et Objets / Encapsulation
L’Encapsulation permet de définir les niveaux de visibilité des éléments de la classe. Ces niveaux de visibilité définissent les droit d’accès aux données selon que l’on y accède par une méthode de la classe elle-même ou bien d’une classe héritière. Abstraction de données :la structure d'un objet n'est pas visible de l'extérieur, son interface est constituée de messages invocables par un utilisateur. La réception d'un message déclenche l'exécution de méthodes. Une structure de données est la même chose qu'une classe mais, par défaut, les membres y sont publics et il n’ya pas de . les niveaux de visibilité en C++ : public : les attributs dits publics sont accessibles à tous, protégé : les attributs dits protégés sont accessibles aux classes dérivées ( aux classes de la même descendance). privé : les attributs privés sont accessibles seulement par l'objet lui-même. Static : attributs de classes , communs à tous les objets de la classe La classe est un type et l’objet est une instance de la classe.

27 Classes et Objets / Encapsulation
Par défaut les membres des classes sont privés. class nom { les membres déclarés ici sont privés public: les membres déclarés ici sont publics private: etc. }; La classe est un type et l’objet est une instance de la classe. Les expressions public: et private: peuvent apparaitre un nombre quelconque de fois dans une classe. Les membres déclarés après private: (resp. public:) sont privés (resp. publics) jusqu'à la fin de la classe, ou jusqu'à la rencontre d'une expression public: (resp. private:).

28 Classes et Objets / Encapsulation
Const pour améliorer la fiabilité du code : remplacer les définitions des Macros ; garantir que les fonctions ne modifient pas l’objet transmis par référence ou par adresse (pointeur). # define Min 1 // min n’est pas défini pour le débogueur Const int Max = 10; // Max défini pour le debogueur Const void fonction (const Point* p) // fonction de consultation { // peut retrouve sa valeur après l’appel de la fonction } La classe est un type et l’objet est une instance de la classe.

29 Classes et Objets / Encapsulation
FONCTIONS MEMBRES Les fonctions membres d'une classe ont le droit d'accéder à tous les membres de la classe. (peuvent rien se cacher). Les getters et les setters (accesseurs et mutateurs) permettent d’accéder et de modifier les attributs. class Point { public: void afficher() { cout << '(' << x << ',' << y << ')‘; } void placer(int a, int b) { validation des valeurs de a et b; x = a; y = b; double distance(Point autrePoint) { int dx = x - autrePoint.x; int dy = y - autrePoint.y; return sqrt(dx * dx + dy * dy);} private: int x, y; }; La classe est un type et l’objet est une instance de la classe.

30 Fichiers d’entête et d’implémentation
Fichier d’en-tête Fichier Point.h : class Point { public: void placer(int a, int b) { validation de a et b x = a; y = b; } double distance(Point autrePoint); private: int x, y; }; La classe est un type et l’objet est une instance de la classe.

31 Fichiers d’entête et d’implémentation
Fichier d’implémentation Fichier Point.cpp : #include <Point.h> #include <math.h> double Point::distance(Point autrePoint) { int dx = x - autrePoint.x; int dy = y - autrePoint.y; return sqrt(dx * dx + dy * dy); } La classe est un type et l’objet est une instance de la classe.

32 Fichiers d’entête et d’implémentation
Fichier Main Fichier Main.cpp : #include <Point.h> Void main() { Point *p=new Point(); } La classe est un type et l’objet est une instance de la classe.

33 Classes et Objets / Constructeurs
Un constructeur d'une classe est une fonction membre spéciale qui : • a le même nom que la classe, • n'indique pas de type de retour, donc pas d'instruction return. Le rôle d'un constructeur est d'initialiser un objet, notamment en donnant des valeurs à ses données membres. Le constructeur n'a pas à s'occuper de trouver l'espace pour l'objet ; il est appelé (immédiatement) après que cet espace ait été obtenu. La classe est un type et l’objet est une instance de la classe.

34 Classes et Objets / Constructeurs
class Point { public: Point(int a = 0, int b = 0) { validation de a et b x = a; y = b; } private: int x, y; }; Comme l'exemple ci-dessus le montre, lorsqu'une fonction fait l'objet d'une déclaration et d'une définition séparées, comme le constructeur Point, les éventuelles valeurs par défaut des argument concernent la déclaration, non la définition. Lorsqu'une fonction fait l'objet d'une déclaration et d'une définition séparées, les noms des arguments ne sont utiles que pour la définition. Point a(3, 4); Point b = Point(5, 6); Point *pt; pt = new Point(1, 2); Point a = Point(1, 2); La classe est un type et l’objet est une instance de la classe.

35 Classes et Objets / Destructeurs
Un destructeur est une fonction membre spéciale. Il a le même nom que la classe, précédé du caractère ~. Il n'a pas de paramètre, ni de type de retour. Il y a donc au plus un destructeur par classe. Le destructeur d'une classe est appelé lorsqu'un objet de la classe est détruit, juste avant que la mémoire occupée par l'objet soit récupérée par le système. class PointNomme { * label; ~PointNomme() { delete [] label; } }; Il y’a au plus un destructeur , par contre on peut y avoir plusieurs destructeurs.

36 Classes et Objets / Destructeurs
Si le programmeur n'a pas écrit de destructeur pour une classe, le compilateur en synthétise un, de la manière suivante : • si la classe n'a ni objets membres ni classes de base alors il s'agit du destructeur trivial qui consiste à ne rien faire, • si la classe a des classes de base ou des objets membres, le destructeur synthétisé consiste à appeler les destructeurs des données membres et des classes de base La classe est un type et l’objet est une instance de la classe.

37 Classes et Objets / Autoreferencement
Dans une fonction membre, On peut se référer directement aux membres de l’objet pour lequel la fonction membre a été invoquée. Le pointeur this est déclaré implicitement comme X const this. Le pointeur this ne peut être modifié mais la valeur qu’il pointe, elle , peut être modifiée. La classe est un type et l’objet est une instance de la classe.

38 Travaux Pratiques Constructeurs , destructeurs Accesseurs , Mutateurs
Fonctions membres.

39 Fonctions et classe amies
class Tableau { int *tab, nbr; friend void afficher(const Tableau &); public: Tableau(int nbrElements);}; Une fonction amie d’une classe est une fonction , qui bien que non membre de la classe a accès aux données privées de la classes. Il importe peu de la déclarer dans la partie publique ou privée. Et plus loin ou dans un autre fichier void afficher(const Tableau &t) { cout << '['; for (int i = 0; i < t.nbr; i++) cout << ' ' << t.tab[i]; cout << ]" ;" } Affichage des éléments d’une liste chainée. Note. Notez cet effet de la qualification friend : bien que déclarée à l'intérieur de la classe Tableau, la fonction afficher n'est pas membre de cette classe ; en particulier, elle n'est pas attachée à un objet, et le pointeur this n'y est pas défini Il y a cependant des cas de figure où une fonction doit être nécessairement écrite comme une amie d'une classe et non comme un membre ; un de ces cas est celui où la fonction doit, pour des raisons diverses, être membre d'une autre classe. Imaginons, par exemple, que la fonction afficher doive écrire les éléments d'un objet Tableau dans un certain objet Fenêtre

40 Fonctions et classes amies
Une classe amie d'une classe C est une classe qui a le droit d'accéder à tous les membres de C. Une telle classe doit être déclarée dans la classe C (la classe qui accorde le droit d'accès), précédée du mot réservé friend, class Pile { Maillon *top; public: Pile() {top = 0; } bool vide() { return top == 0; } void empiler(int x) { top = new Maillon(x, top); int sommet() { return top->info; } } class Maillon { int info; Maillon *suivant; Maillon(int i, Maillon *s) { info = i; suivant = s; } friend class Pile; }; La relation d'amitié n'est pas transitive, « les amis de mes amis ne sont pas mes amis. La relation d’amitié n’est pas reflexive. La classe pile est amie de la classe Maillon cela ne veut pas dire que la classe maillon est amie de la classe Pile.

41 Surcharge des Opérateurs
En C++ on peut redéfinir la sémantique des opérateurs du langage, soit pour les étendre à des objets, alors qui n'étaient initialement définis que sur des types primitifs, soit pour changer l'effet d'opérateurs prédéfinis sur des objets. Cela s'appelle surcharger des opérateurs. Il n'est pas possible d'inventer de nouveaux opérateurs ; seuls des opérateurs déjà connus du compilateur peuvent être surchargés. Tous les opérateurs de C++ peuvent être surchargés sauf : . , .* , :: , ?: et le sizeof Une fois surchargés, les opérateurs gardent leur pluralité, leur priorité et leur associativité initiales. En revanche, ils perdent leur éventuelle commutativité et les éventuels liens sémantiques avec d'autres opérateurs. .

42 Surcharge des Opérateurs
Surcharger un opérateur revient à définir une fonction ; tout ce qui a été dit à propos de la surcharge des fonctions s'applique donc à la surcharge des opérateurs. il faut définir une fonction nommée operator qui peut être une fonction membre d'une classe ou bien une fonction indépendante. Les deux surcharges de + comme celles montrées ci-dessus, par une fonction membre et par une fonction non membre, ne peuvent pas être définies en même temps dans un même programme ; p + q est ambiguë pour le compilateur. .

43 Surcharge des Opérateurs
Travaux pratiques sur la surcharge des opérateurs. Devoir à la maison .

44 Relation entre objets UML
Les objets vont communiquer entre eux en s'envoyant des messages: dans la réalité, ces messages sont tout simplement des appels de fonctions, comme on l'a vu. Les objets sont en relation entre Association C'est la plus courante, aussi la moins forte: c'est la relation qui lie un enseignant et ses étudiants, par exemple. Agrégation C'est la relation qui lie un objet et ses composants: la cafetière et son réservoir d'eau, de café, de gobelets, par exemple. Elle est plus forte que la relation d'association, toutefois une cafetière peut exister sans son réservoir à café. Composition La relation la plus forte .Un immeuble de 10 étages ne peut exister sans tous ses étages, et réciproquement: on exprimera donc dans le code le fait que si l'objet immeuble est détruit, tous les objets le composant seront détruits également, et réciproquement. Une sorte de On pourra exprimer le fait qu'une machine à café particulière est "une sorte de" machine à café. Un tas de Des objets particuliers (les conteneurs) nous permettront de mettre nos objets dans des structures de données: on pourra donc avoir "un tableau de cafetières", "une pile de cafetière", "une queue de cafetières", etc. eux (un objet en relation avec aucun autre objet ne servirait à rien). On distingue plusieurs types de relations: Les relations d'association, d'agrégation et de composition s'expriment en insérant des variables membres dans une définition de classe (). Dans le cas de la relation de composition, il convient de s'assurer que les objets sont construits ou détruits ensemble. La relation "est une sorte de" s'exprime grâce à l'héritage ( ). Les autres relations s'expriment par les modèles () Lees bases de donnees spatiales : Google map. Base de données objets. Lourdeurs des contraintes d’intégrités. ( objet références). Nouveaux types de données image , dessin video Incompletude du language SQL ( macchine de turing théorie des languages). Language compets est un language capable de décrire tous les alogorithmes.

45 Héritage Person Employe
Le terme héritage désigne le principe selon lequel une classe peut hériter des caractéristiques (attributs et méthodes) d'autres classes. Le mécanisme de l'héritage consiste en la définition d'une classe par réunion des membres d'une ou plusieurs classes préexistantes, dites classes de base directes, et d'un ensemble de membres spécifiques de la classe nouvelle, appelée alors classe dérivée Lorsqu’il ya plusieurs classes de base on parle d’héritage multiple. Classe de base Classe dérivée Person Ne pas réinventer la roue Employe

46 Héritage : intérêts L'héritage permet la réutilisation de code existant : une nouvelle classe réutilise les attributs et les méthodes d'une classe existante et y ajoute les propriétés (attributs et méthodes) particulières à la nouvelle classe. On peut ainsi : étendre les fonctionnalités d'une classe existante. adapter une classe à une situation particulière (spécialisation). .

47 Héritage Les classes dérivées ne peuvent accéder directement qu’aux variables publics et protégés. Les constructeurs, les destructeurs et les amis ne sont pas hérités. Il existe trois mode d’héritage : public, private et protected .

48 Héritage et accessibilité des membres
Mode d’héritage Classe de base Classe dérivée public protected private Protected Private .

49 Héritage : Constructeurs des classes dérivées
Si une classe dérivée utilise un constructeur elle doit utiliser le constructeur de sa classe de base Dans ce cas la classe de base se comporte exactement comme un membre de la classe dérivée. Le constructeur Base() est d’abord appelé ; si on ne fait pas appel à ce constructeur C++ générera un appel automatique au constructeur défini par le système. Qu’on ait ou pas défini un constructeur explicite pour cette classe de base. Puis les initialisations relatives aux données propres à la classe dérivée ont lieu. .

50 Héritage : implémentation de l’héritage
Travaux pratiques : personne , employee .

51 Polymorphisme et implémentation
Si la classe D dérive publiquement de la classe B alors les membres de B sont membres de D. Autrement dit, les membres publics de B peuvent être atteints à travers un objet D. Ou encore : tous les services offerts par un B sont offerts par un D. Par conséquent, là où un B est prévu, on doit pouvoir mettre un D. Le polymorphisme représente aussi la possibilité pour des objets de même descendance à répondre différemment lors de l’appel d’une fonction de même nom, .

52 Polymorphisme et implémentation
Fonction polymorphe : implanté via une fonction virtuelle substituée. Soit f une fonction membre d'une classe C. Si les conditions suivantes sont réunies : • f est redéfinie dans des classes dérivées (directement ou indirectement) de C, • f est souvent appelée à travers des pointeurs ou des références sur des objets de C ou de classes dérivées alors f mérite d'être une fonction virtuelle. L'important service obtenu est celui-ci : si f est appelée à travers un pointeur ou une référence sur un objet de C, le choix de la fonction effectivement activée, parmi les diverses redéfinitions de f, se fera d'après le type dynamique de cet objet. Une classe possédant des fonctions virtuelles est dite classe polymorphe. Virtual void dessiner() : figure, rectangle , triangle, cercle La définition de la fonction à appeler sera sélectionnée de façon dynamique selon la classe de l’objet pointé et non du type de pointeur. .

53 Polymorphisme et implémentation
Une fonction surchargée n’est pas une fonction virtuelle ( avec la même signature et des types différents). Comment traiter un objet Person lorsque cette personne décède ? Appel à ~Person() , mais si c’est aussi un employé ? Appel à ~Employee() mais si c’est aussi un manager ? … Les destructeurs virtuels garantissent l’appel des destructeurs appropriées dès qu’une suppression s’applique à un pointeur de classe de base. Class A{~A();} Class B : public A{virtual ~B();} A* p=(A*) new B(); delete p; Donc p->~B(); Sans virtuel : p->~A(); et c’est insuffisant. .

54 Polymorphisme et implémentation
Classes abstraites = classer non instanciable Class abstraite { Public : virtual int pure()=0; //fonction virtuelle pure } // le programme ne peut créer une instance de classe abstraite Le présence d’une fonction virtuelle pure dans une classe a deux conséquences : La classe en question ne peut plus être instanciée directement; Toute classe dérivant de cette classe doit normalement redéfinir la fonction virtuelle pure. Donc lorsqu’une classe contient une fonction virtuelle pure alors elle est abstraite. .

55 Problème Imaginons qu’on veut écrire un programme de gestion globale de l’IUT, s’occupant à la fois des étudiants et du personnel. Les etudiants ont chacun une moyenne annuelle. Ils sont divisés en plusieurs groupes. Tout membre du personnel a un bureau. On distingue le personnel administratif du personnel enseignant. Chaque enseignant détient numéro de casier . Tout membre du personnel reçoit un salaire à la fin du mois. Ce pendant les vacataire qui font partie du personnel vacataire sont payés à l’heure et n’ont pas de salaire mensuel fixe( permanent). chaque personne est désignée par un nom et une adresse. On vous demande de donner le digramme de classe . .

56 Personne Personnel Etudiant Administratif Enseignant vacataire
#nom char * #adresse : char * Personnel Etudiant #bureau : int +calculersalaire() #moyenne : double Administratif Enseignant #salaire_mensuel +calcul_salaire(m) #casier : int +calculsalaire(m) . vacataire Permanent #tarif_horaire : doubl Nb_heures : int +calculsalaire(m) #salaireMensuel :do #calculSalaire()

57 Les Templates : les modèles de fonctions
Jusqu'ici on passait en paramètre des fonctions des variables. Grâce au concept de template, il est possible de passer en paramètre des types et ainsi de définir des fonctions génériques. Les modèle de fonctions sont des fonctions spéciales qui évitent de créer une fonction différentes pour chaque type. Avantages : généricité et simplcité. Inconvénients : programmes plus long à compiler. Le format de déclaration d’une fonction Template est : template <class identifier> declaration_de_la _fonction; template <typename identifier> declaration_de_le_fonction; .

58 Les Templates : les modèles de fonctions
// function template II # include <iostream> using namespace std; template <class T> T GetMax (T a, T b) { return (a>b?a:b); } int main () { int i=5, j=6, k; long l=10, m=5, n; k=GetMax(i,j); n=GetMax(l,m); cout << k << endl; cout << n << endl; return 0; .

59 Les Templates : les modèles de fonctions
Fonctions template avec plusieurs paramètre template <class T, class U> T GetMin (T a, U b) { return (a<b?a:b); } .

60 Les Templates : les modèles de classes
Nous pouvons aussi implémenter les classe génériques : template <class T> class mypair { T values [2]; public: mypair (T first, T second) { values[0]=first; values[1]=second; } }; mypair<int> myobject (115, 36); mypair<double> myfloats (3.0, 2.18); Implémentation des Listes génériques .

61 Les Templates : les modèles de classes
// class templates #include <iostream> using namespace std; template <class T> class mypair { T a, b; public: mypair (T first, T second) {a=first; b=second;} T getmax (); }; template <class T> T mypair<T>::getmax () { T retval; retval = a>b? a : b; return retval; } int main () { mypair <int> myobject (100, 75); cout << myobject.getmax(); return 0; } .

62 Les conteneurs de la STL : Satandard Template Library
STL est une Library C++ contenant des classes des algorithmes une classe contenant un ensemble d’éléments d'un certain type est appelé conteneur . Les conteneurs de la STL sont un exemple d’utilisation des templates. La bibliothµeque standard (STL) fournit divers conteneurs tels que des listes, des vecteurs, des piles, des files d'attente, des tableaux associatifs (Map), etc. Les listes sont des séquences ordonnées d‘éléments d'un certain type. Elles sont implémentées à l'aide de listes doublement chainées : template <class Object> class list { ... }; List<int> Maliste . Les vecteurs sont des listes implémentées à l'aide de tableaux. Ils remplacent avantageusement les tableaux standards du C car leur taille est implicite et peut être redéfinie. De plus, on peut affecter un vecteur dans un autre à l'aide de l'opérateur d'affectation : vector<int> monvecteur; Les maps constituent une association <clé,valeur>map<std::string,unsigned> lesMois; .

63 Fonctions communes à tous les conteneurs
int size() const: Retourne le nombre d‘éléments dans le conteneur void clear(): Enlève tous les éléments bool empty(): Détermine si le conteneur est vide. .

64 Fonctions communes à vector et list
void push_back(const Object& x): Ajoute x à la fin du conteneur. void pop_back(): Enlève le dernier objet du conteneur const Object& back() const: Retourne l'objet situé à la fin du conteneur const Object& front() const: Retourne l'objet situé au début du conteneur Fonctions propres aux list : void push_front(const Object& x): Ajoute x au début du conteneur void pop_front(): Enlève le premier objet du conteneur Fonctions propre aux vector Object& operator[] (int i): Retourne l'objet situé à la position i du conteneur Object& at (int i): Comme le précédent mais avec un contrôle de la plage des valeurs. Déclenche une exception out of range lorsqu'un indice est incorrect. void resize( int nouvelle taille): Redéfini la taille du conteneur int capacity() const: Retourne la capacité du conteneur void reserve(int nouvelle capacite): Redéfini la capacité du conteneur .

65 Fonctions membres utilisant les itérateurs
Plusieurs fonctions requierent la notion de position dans un conteneur. Dans la STL une position est représentée par un type imbriqué que l'on nomme itérateur. Par exemple, on utilise le type vector<string>::iterator pour représenter une position dans un vector<string>. Pour plus de concision nous écrirons simplement iterator. iterator begin(): Retourne un iterateur pointant au début du conteneur iterator end(): Retourne un itérateur pointant à la fin du conteneur iterator insert (iterator p, const Object& x): Ajoute x immédiatement avant la position p. iterator erase (iterator p): Enlève l'objet à la position p. Retourne la position de l'objet suivant. iterator erase(iterator debut, iterator fin): Enlève tous les objets à partir de debut jusqu’à fin. .

66 Fonctions membres utilisant les itérateurs
Si v est une variable de type vector<int> alors on peut afficher ses éléments de la façon suivante: for (int i=0; i< v.size(); ++i) cout<<v[i]<<endl; On peut aussi utiliser la méthode suivante: for (vector<int>::iterator itr=v.begin(); itr!= v.end(); ++itr) cout<<*itr<<endl; std::sort(myvector.begin(),myvector.end(), lafonctionpredicate); .

67 Les MAP Association clé valeur map<string,string > monmap; une clé est associées à une et une seule valeur. Les multimap : association d’une clé à une ou plusieurs valeur. multimap<string,int> repmult; repmult.insert(pair<string,int>("sylla", )); pair<multimap<string,int>::iterator, multimap<string,int>::iterator> pairit; pairit=repmult.equal_range("sylla"); Equal_range : returns the bounds of a range that includes all the elements in the container with this key. (retourne une paire d ietrateurs qui delimite l ensemeble des elements du conteneur possedant cette cle) Un intervalle des element ayant cette cle delimite par des iterateur debut et fin. .

68 Les conteneurs de la STL
Travaux pratiques : List , Vector et Map List ou vector d’objets ( personne). reverse( v.begin(), v.end() ); Ax2 + bx + c = 0 delta = b*b – 4ac R = [j+ int(2.6(M-2))+ int(A/4) + A)] mod 7 0 samedi 6 vendredi .

69 La Gestion des Exceptions
En programmation, quel que soit le langage utilisé ,il existe plusieurs types d'erreurs qui peuvent survenir. (Syntaxique, sémantique) Un autre type de problèmes peut survenir si le programme est écrit correctement mais qu'il exécute une action interdite. ( division par zero , racine carrée d’un nombre négatif) erreurs d'implémentation. La gestion des exceptions permet, si elle est réalisée correctement, de corriger les erreurs d'implémentation en les prévoyant à l'avance. Le mécanisme des exceptions est destiné à permettre aux fonctions profondes d'une bibliothèque de notifier la survenue d'une erreur aux fonctions hautes qui utilisent la bibliothèque. .

70 La Gestion des Exceptions
Les points-clés de ce mécanisme sont les suivants : la fonction qui détecte un évènement exceptionnel construit une exception et la lance (throw) vers la fonction qui l'a appelée ; l'exception est un nombre, une chaîne ou, mieux, un objet d'une classe spécialement définie dans ce but (souvent une classe dérivée de la classe exception) comportant diverses informations utiles à la caractérisation de l‘évènement à signaler ; une fois lancée, l'exception traverse la fonction qui l'a lancée, sa fonction appelante, la fonction appelante de la fonction appelante, etc., jusqu‘à atteindre une fonction active (une fonction commencée et non encore terminée) qui a prévu d' attraper (catch) ce type d'exception ; lors du lancement d'une exception, la fonction qui l'a lancée et les fonctions que l'exception traverse sont immédiatement terminées : les instructions qui restaient à exécuter dans chacune de ces fonctions sont abandonnées ; malgré son caractère prématurée, cette terminaison prend le temps de détruire les objets locaux de chacune des fonctions ainsi avortées ; .Les interruptions en assembleur

71 La Gestion des Exceptions
si une exception arrive à traverser toutes les fonctions actives, car aucune de ces fonctions n'a prévu de l'attraper, alors elle produit la terminaison du programme; Une fonction indique qu'elle s'intéresse aux exceptions qui peuvent survenir durant l'exécution d'une certaine séquence d'instructions par une expression qui d'une part délimite cette séquence et qui d'autre part associe un traitement spécifique aux divers types d'exception que la fonction intercepte. Try{ }catch(exception1 e) { }catch(exception2 e1){} Un bloc try doit être immédiatement suivi par au moins un gestionnaire catch. Un gestionnaire catch doit se trouver immédiatement après un bloc try ou immédiatement après un autre gestionnaire catch .Les interruptions en assembleur

72 La Gestion des Exceptions
const int DivideByZero = 10; //... double divide(double x, double y) { if(y==0) { throw DivideByZero; } return x/y; } try { divide(10, 0); } catch(int i) { if(i==DivideByZero) { cerr<<"Divide by zero error"; } .Les interruptions en assembleur

73 La Gestion des Exceptions
void foo() { throw new MyApplicationException(); } void bar() { try { foo(); } catch(MyApplicationException* e) { // Handle exception } Cout<<«  »<<e->what(), .Les interruptions en assembleur

74 La Gestion des Exceptions
#include <string> int division(int a,int b) { if(b == 0) throw std::string("ERREUR : Division par zéro !"); else return a/b; } try{ std::cout << a << " / "<<b << " = " << division(a,b) << std::endl; } catch(const std::string& chaine) { std::cerr << chaine << std::endl; } .Les interruptions en assembleur

75 La Gestion des Exceptions
Exercice racine carrée et division . .Les interruptions en assembleur

76 MERCI POUR VOTRE ATTENTION
.Les interruptions en assembleur


Télécharger ppt "Faculté de Génie Informatique UNC Le Langage C++"

Présentations similaires


Annonces Google