Télécharger la présentation
Publié parValérie Coste Modifié depuis plus de 9 années
1
Introduction à la programmation objet en C++
PRO-1027 Programmation Scientifique en C Introduction à la programmation objet en C++ Sujets POO et C++ Différences entre C++ et C Notions de classes Références:
2
POO et C++ Le langage C++ a été développé à partir de 1982 par Bjarne Stroustrup (AT&T Bell laboratories) avec un objectif précis, soit ajouter au langage C des « classes » analogues à celles du langage Simula. Les langages de Programmation Structurée sont fondés sur la notions d’Algorithmes et de Structures de données, à partir desquelles nous concevons des Programmes. Les langage de Programmation Orientée Objet (POO) sont quant à eux basés sur la notion de classes abstraites. L’instanciation d’une classe produit un objet découlant de cette classe. Cet objet est caractérisé par des Attributs (données) et des Méthodes.
3
POO et C++ De la notion de classe découle le qualificatif orienté objet à C++ qui est fondé justement sur C. La notion de classe repose sur le concept d’encapsulation des données et des méthodes qui consiste à ne pas séparer les données des opérations qui agissent sur elles. Une classe, dans un langage de classe, est un nouveau type de données qui en plus des données, contient les méthodes permettant de manipuler ces données. Une classe étant définie, elle forme un tout et ne peut être utilisée que sous la forme d’interface choisie. Certaines variables (attributs) peuvent être privées, autrement dit inaccessibles de l’extérieur de cette classe. Une classe est constituée : De Données et de Méthodes agissant sur ces données .
4
POO et C++ Notions d’encapsulation
L’encapsulation stipule qu’on ne peut pas agir directement sur les données d’un objet. Il faut passer par l’intermédiaire de ses méthodes qui jouent le rôle d’interface. Vu de l’extérieur, un objet est caractérisé uniquement par les spécifications de ses méthodes (noms, arguments et rôle), la manière dont sont implantées les données étant sans importance, cachées, encapsulées. L’encapsulation des données facilite la maintenance des logiciels : une modification éventuelle de la structure de données d’un objet n’a d’incidence que sur l’objet lui-même; les utilisateurs de l’objet ne seront pas concernés par la teneur de cette modification. L’encapsulation facilite également la réutilisation des objets.
5
Différences entre C++ et C
La différence la plus fondamentale est le fait que C++ soit OO. Autre différence: Passage de paramètres par référence Exemple de la fonction swap() En C++, il existe la notion de transmission d’arguments par référence, qui facilite énormément l’écriture de fonctions. L’exemple de la fonction swap() en C++ : void swap(int & x, int & y){ int temp; temp = x; x = y; y = temp;} Cette fonction peut être appelée comme suit : int x=3, y=5; swap(x,y); La notation int & x signifie que x est une information entière transmise par référence. C’est le compilateur qui s’occupe du passage des paramètres.
6
Différences entre C++ et C
Arguments de fonctions par défaut En C, il faut que l’appel d’une fonction contienne autant d’arguments que la fonction en attend effectivement. C++ permet de contourner cette règle par un mécanisme d’attribution de valeurs par défaut à des arguments. #include <iostream.h> main () { int a=10, b=20; void fct(int, int = 12); // prototype avec une valeur par défaut fct (a, b); //appel normal fct(a);// appel avec un seul argument } void fct(int a, int b) //en-tête habituelle cout << "premier argument : " << a << "\n"; // premier argument : 10 10 cout << "second argument : " << b << "\n"; // second argument : Appel normal Appel avec un argument
7
Différences entre C++ et C
Arguments de fonctions par défaut int = 12 dans la déclaration de la fonction fct indique au compilateur, qu’en cas d’absence de ce second argument dans un appel éventuel de la fonction fct(), il faut lui affecter cette valeur (par défaut). L’appel à la fonction fct() sans argument sera rejeté à la compilation. On peut prévoir des valeurs par défaut pour tous les arguments d’une fonction. On constate que les valeurs par défaut sont fixées dans la déclaration de la fonction et non dans sa définition. Par conséquent, ce n’est pas le concepteur de la fonction qui décide des valeurs par défaut mais plutôt son utilisateur. Cependant, si la déclaration de la fonction est figée dans un fichier d’en-tête, l’utilisateur ne peut plus choisir les valeurs par défaut. Pour éviter toute confusion, les arguments avec des valeurs par défaut doivent être spécifiés les derniers de la liste.
8
Différences entre C++ et C
Surcharge des opérateurs et des fonctions La surcharge signifie qu’un même symbole possède des significations différentes, selon le contexte. Certains opérateurs sont déjà surchargés en C. Par exemple : L’opérateur * peut désigner une multiplication d’entiers, de flottants ou une indirection : int *p; L’opérateur / peut désigner une division de flottants ou une division entière (div). En C++, la plupart des opérateurs peuvent être surchargés. Surcharge de fonctions : #include <iostream.h> //Les prototypes void fct (int); // prototype 1: fct void fct (double); // prototype 2: fct main(){ int n = 5; double x = 2.5; fct (n); fct (x);} //Première fonction fct: int void fct(int a){ cout << "fct version int a = " << a << "\n";} // Affiche 5 //Deuxième fonction fct: double void fct(double a){ cout << "fct version double a = " << a << "\n";} // Affiche 2.5
9
Différences entre C++ et C
Surcharge des opérateurs et des fonctions Règles: fonction à un argument Le compilateur cherche la meilleure correspondance possible. Il existe plusieurs niveaux de correspondance : Correspondance exacte : les types correspondent exactement. Correspondance avec promotion numérique : char ou short à int float à double Conversions "standard" : les conversions légales en C++, sont celles qui peuvent être imposées par une affectation (sans cast). La recherche s’arrête au premier niveau ayant permis de trouver une correspondance. Cette dernière doit être unique sinon, il y a ambiguïté. Si aucune fonction ne convient à aucun niveau, il y a également erreur de compilation. Règles: fonction à plusieurs arguments Le compilateur cherche la meilleure fonction. Le compilateur commence par sélectionner, pour chaque argument, la ou les fonctions qui réalisent la meilleure correspondance. Parmi ces fonctions, il choisit celle qui réalise, pour chaque argument, une correspondance au moins égale à celle de toutes les autres; si elle n’existe pas ou elle n’est pas unique, il y a une erreur.
10
Différences entre C++ et C
Surcharge des opérateurs et des fonctions Exemples: void test (int n=0, double x=0); //test 1 void test (double y=0, int p=0); //test 2 int n; double z; test (n,z); // la fonction test 1 est appelee test(z,n); // la fonction test 2 est appelee test(n); // la fonction test 1 est appelee test(z); // la fonction test 2 est appelee test(); // produit une erreur de compilation
11
Différences entre C++ et C
Surcharge des opérateurs et des fonctions Exemples: void essai (int, double); //essai 1 void essai (double, int); //essai 2 int n, p; double z; char c; essai (n,z); // la fonction essai 1 est appelee essai (z,c); // la fonction essai 2 est appelee essai (n,p); // la fonction essai 1 est appelee
12
Différences entre C++ et C
Opérateurs new() et delete() En langage C, la fonction malloc() permet d’allouer de l’espace mémoire dynamiquement et free() pour le libérer. Ces deux fonctions sont également utilisables en C++. C++ a introduit deux autres opérateurs adaptés à la gestion des objets : new() et delete(). Ces opérateurs peuvent également être utilisés avec les autres types de variables. // En langage C int * p; p = (int *)malloc(sizeof(int)); // En lanagage C++ p = new int; // int * p = new int; // En langage C char * p2; p2 = (char *)malloc(100); // En langage C++ p2 = new char[100];
13
Différences entre C++ et C
Opérateurs new() et delete() new type; retourne un pointeur de type (type *) sur le début du bloc mémoire réservé lorsque l’allocation a réussi un pointeur nul (NULL = 0) dans le cas contraire. new type [n]; où n est une expression entière quelconque, réserve un bloc mémoire nécessaire pour n éléments du type indiqué et retourne l’adresse du premier élément de ce tableau. new type[n][10]; Retourne un pointeur de type type * [10]. La première dimension peut être une expression entière quelconque; les autres dimensions doivent être des expressions constantes.
14
Différences entre C++ et C
Opérateurs new() et delete() Il faut absolument utiliser la fonction delete() pour libérer un bloc mémoire alloué préalablement par new(). int * p; p = new int; //Utilisation de p delete p; int * p2; p2 = new char[100]; //Utilisation de p2 delete p2;
15
Notions de classes en C++
Les classes et les structures Définition d’une structure en C: struct point { int x; int y; }; Déclaration : struct point a, b; Les structures en C++ : En C++, outre les données membres d’une structure, on peut avoir des méthodes ou fonctions membres. Cependant, cette association entre données et méthodes au sein de la même classe ne permet pas d’encapsuler les données.
16
Notions de classes en C++
#include <iostream.h> struct point { //les données membres int x; int y; //les fonctions membres (méthodes) void initialise (int, int); void deplace (int, int); void affiche(); }; void point ::initialise(int abs, int ord) x = abs; y = ord; } void point ::deplace(int dx, int dy) x += dx; y += dy; void point ::affiche() cout << " Position 2D :" << x << " " << y << "\n";
17
Notions de classes en C++
main () { struct point a, b; a.initialise(5,2); a.affiche(); // Position 2D : 5 2 a.deplace(-2,4); a.affiche; // Position 2D : 3 6 b.initialise(1,-1); b.affiche; // Position 2D : 1 -1 a.x = 5; //accès direct aux données a.y = 2; //accès direct aux données cout << "Position 2D main : " << a.x << " " << a.y << "\n"; //accès direct aux données }
18
Notions de classes en C++
Déclaration d’une classe class nom_de_classe { public : type1 attribut 1 type2 attribut 2 fonction public 1 (paramètres) … private : type3 nom_de_champ3 type4 nom_de_champ4 fonction private 1 (paramètres) } class CRectangle public: void init_valeur (int,int); int surface (void); private: int a, b; } ;
19
Notions de classes en C++
Déclaration d’une classe (CRectangle) Une nouvelle classe (i.e., un nouveau type) CRectangle est déclarée. Cette classe contient 4 membres: deux attributs de type int (membre a et le membre b) avec un accès privé. deux fonctions avec un accès public: init_valeur() et surface(). Après la déclaration de la classe CRectangle, une instance de cette classe, un objet peut alors être déclarée: CRectangle rect; Il est possible de référer à chaque membre public de l’objet rect à partir du corps du programme comme si ils étaient des fonctions ou des variables conventionnelles. int surfaceRect; rect.init_valeur (10,5); surfaceRect = rect.surface(); // surfaceRect = 50;
20
Notions de classes en C++
Déclaration d’une classe (Classe point) #include <iostream.h> class point { private : //facultatif int x, y; public : void initialise (int, int); void deplace (int, int); void affiche ();}; void point ::initialise(int abs, int ord){ x = abs; y = ord;} void point ::deplace(int dx, int dy){ x += dx; y += dy;} void point ::affiche(){ cout << "Position 2D ; " << x << " " << y << "\n";}
21
Notions de classes en C++
Déclaration d’une classe (Classe point) main (){ point a, b; a.initialise(5,2); a.affiche(); a.deplace(-2,4); a.affiche; b.initialise(1,-1); b.affiche();} La définition des fonctions se fait comme avec les structures. Les fonctions membres d’une classe ont accès à tous les membres de la classe (publics ou privés).
22
Notions de classes en C++
Déclaration d’une classe (Classe point) À cause de l’encapsulation, des instructions comme : a.x = 5; ou cout << a.y ; dans la fonction principale main() ne sont par permises. En effet, les données x et y sont privées. Par conséquent, elles ne sont visibles qu’à l’intérieur de la classe par l’intermédiaire des méthodes de la classe point. Les mots clés public et private peuvent apparaître à plusieurs reprises dans la définition d’une classe. Si aucun d’eux n’apparaît au début de la définition, on considère qu’il s’agit de membres privés. Il existe un autre mot clé : protected qui définit un statut intermédiaire entre public et privé. Ce mot n’intervient que dans le cas de classes dérivées.
23
Notions de classes en C++
Déclaration d’une classe Une fonction membre d’une classe peut accéder à tous les membres de cette classe, qu’ils soient publics ou privés. Il existe deux façons de définir une fonction membre : La définition à l’intérieur même de la déclaration de la classe. La déclaration à l’extérieur de la classe (voir les classes CRectangle et point)
24
Notions de classes en C++
Déclaration d’une classe (définition des méthodes) #include <iostream> using namespace std; class CRectangle { int a, b; public: void init_valeur (int,int); int surface () { return (a*b);} }; void CRectangle::init_valeur (int x, int y) { a = x; b = y; } int main () { CRectangle rect; rect.init_valeur (20,15); cout << "Surface: " << rect.surface(); return 0; }
25
Notions de classes en C++
Affectation d’objets En langage C, on peut affecter à une structure la valeur d’une autre structure. En langage C++, on peut aussi affecter à un objet la valeur d’un autre objet. point a, b; a.initialise (4,5); b = a; Tous les membres de l’objet a sont recopiés dans l’objet b, qu’ils soient publics ou privé, à l’exception des parties allouées dynamiquement.
26
Notions de classes en C++
Notions de constructeurs et destructeurs Un constructeur est une fonction membre qui sera appelée automatiquement à chaque création d’une instance (objet) d’une classe. En général, un constructeur est utilisé pour initialiser les variables statiques et allouer les variables dynamiques. Un constructeur porte généralement le même nom que sa classe. Un constructeur peut avoir zéro, un ou plusieurs arguments. Un destructeur est une fonction membre qui sera appelée automatiquement lors de la destruction de l’objet correspondant. En général, un destructeur est utilisé pour libérer l’espace alloué dynamiquement. Un destructeur porte généralement le même nom que sa classe, précédé du symbole tilde (~). Un destructeur ne doit avoir aucun argument.
27
Notions de classes en C++
Notions de constructeurs (Classe CRectangle) #include <iostream> using namespace std; class CRectangle { int largeur, hauteur ; public: CRectangle (int,int); // declaration du constructeur int surface () {return (largeur*hauteur);} }; // definition du constructeur CRectangle::CRectangle (int a, int b) { largeur = a; hauteur = b; }
28
Notions de classes en C++
Notions de constructeurs (Classe CRectangle) int main () { CRectangle rect1 (3,4); CRectangle rect2 (5,6); cout << "Surface rect1: " << rect.surface() << endl; cout << "Surface rect2 : " << rectb.surface() << endl; return 0; }
29
Notions de classes en C++
Notions de destructeurs (Classe CRectangle) #include <iostream> using namespace std; class CRectangle { int *largeur, *hauteur ; public: CRectangle (int,int); // declaration du constructeur ~CRectangle (); // declaration du destructeur int surface () {return (*largeur * *hauteur);} }; CRectangle::CRectangle (int a, int b) { largeur = new int; hauteur = new int; *largeur = a; *hauteur = b; } CRectangle::~CRectangle () { delete largeur; delete hauteur; }
30
Notions de classes en C++
Notions de classes amies Plusieurs classes sont généralement définies dans un même programme. Certaines fonctions s’appliquent sur des objets de classes différentes. Comment alors ces fonctions peuvent-elles accéder aux attributs privés de ces différentes classes étant donné qu’une fonction ne peut pas être simultanément membre de plusieurs classes.
31
Notions de classes en C++
Notions de classes amies #include <iostream> using namespace std; class CCarre; class CRectangle { int largeur, hauteur; public: int surface () { return (largeur * hauteur);} void convert (CCarre a); }; class CCarre { private: int cote; void init_cote (int a) {cote=a;} friend class CRectangle; }; void CRectangle::convert (CCarre a) { largeur = a.cote; hauteur = a.cote; }
32
Notions de classes en C++
Notions de classes amies int main () { CCarre carre; CRectangle rect; carre.init_cote(100); rect.convert(carre); cout << rect.surface(); // 10000 return 0; }
33
Notions de classes en C++
Notions d’héritage L’héritage de classes est une caractéristique fondamentale de C++. L’héritage permet de créer des classes qui sont dérivées d’autres classes permettant ainsi d’automatiquement inclure certains membres de la classe parent en plus de ces propres membres. Supposons que nous déclarons une série de classes permettant de décrire des polygones comme une classe déjà connue CRectangle, ou comme CTriangle. Ces classes ont certaines propriétés communes, comme la hauteur et la base. La classe CPolygon peut alors nous permettre de dériver d’autres classes comme: CRectangle and CTriangle.
34
Notions de classes en C++
Notions d’héritage La classe CPolygon contient des membres qui sont communs aux deux types de polygone (largeur (base) et la hauteur). Les classes CRectangle et CTriangle sont les classes derivées de CPolygon, avec des caractéristiques spécifiques à chaque classe qui sont uniques à chaque type de polygone. Les classes dérivées héritent des membres accessibles de la classe de base. Si par exemple, la classe de base comprend une membre A et que nous dérivons à partir de cette classe une autre classe avec un autre membre B, la classe dérivée contiendra alors les membres A et B. Pour dériver une classe à partir d’une autre, nous utilisons le symbole (:) dans la déclaration de la classe dérivée avec le format: class nom_classe_derivee: public nom_classe_base { /*...*/ }; nom_classe_derivee est le nom de la classe dérivée et nom_classe_base est le nom de la classe de base. Le type d’accès public peut être remplacé par les types d’accès protected et privé. Le type d’accès décrit le niveau d’accès minimum des membres hérités de la classe de base.
35
Notions de classes en C++
Notions d’héritage #include <iostream> using namespace std; class CPolygon { protected: int largeur, hauteur; public: void init_valeur (int a, int b) { largeur=a; hauteur=b;} }; class CRectangle: public CPolygon { int surface () { return (largeur * hauteur); } }; class CTriangle: public CPolygon { int surface () { return (largeur * hauteur / 2); } };
36
Notions de classes en C++
Notions d’héritage int main () { CRectangle rect; CTriangle trgl; rect.init_valeur (4,5); trgl.init_valeur (4,5); cout << rect.surface() << endl; // surface = 20 cout << trgl.surface() << endl; // surface = 10 return 0; }
37
Notions de classes en C++
Notions d’héritage Les objets instantiés à partir des classes CRectangle et CTriangle contiennent chacun des membres hérités de la classe CPolygon (largeur, hauteur, init_valeur(). Le type d’accès protected est similaire au type d’accès private. La différence survient lors de l’héritage. Lorsqu’une classe hérite des membres d’une classe de base, les membres de la classe dérivée ont accès aux membres de la classe de base mais pas les membres private. Sachant que nous voulons que les membres largeur et hauteur de la classe de base soient accessibles aux membres des classes dérivées CRectangle et CTriangle et non seulement par les membres de la classe CPolygon, le type d’accès protected est utilisé au lieu de private. Sommaire des types d’accès en fonction de la façon avec laquelle les membres doivent être accédés:
38
Notions de classes en C++
Notions d’héritage multiples En C++ il est aussi possible qu’une classe hérite des membres de plus d’un classe. Dans la déclaration de la classe dérivée il faut séparer les différentes classes de base héritées par le symbole (,). Par exemple, si nous avons une classe de base COutput qui permet d’effectuer des opérations d’affichage et nous voulons que les classes CRectangle et CTriangle héritent en plus des membres de la classe de base CPolygon aussi ceux de la classe de base COutput: class CRectangle: public CPolygon, public COutput; class CTriangle: public CPolygon, public COutput;
39
Notions de classes en C++
Notions d’héritage multiples #include <iostream> using namespace std; class CPolygon { protected: int largeur, hauteur; public: void init_valeur (int a, int b) { largeur=a; hauteur=b;} }; class COutput { void output (int i); };
40
Notions de classes en C++
Notions d’héritage multiples void COutput::output (int i) { cout << i << endl; } class CRectangle: public CPolygon, public COutput { public: int surface () { return (largeur * hauteur); } }; class CTriangle: public CPolygon, public COutput { int surface () { return (largeur * hauteur / 2); } };
41
Notions de classes en C++
Notions d’héritage multiples int main () { CRectangle rect; CTriangle trgl; rect.init_valeur (4,5); trgl.init_valeur (4,5); rect.output (rect.surface()); trgl.output (trgl.surface()); return 0; }
Présentations similaires
© 2024 SlidePlayer.fr Inc.
All rights reserved.