18
C++ : classes Introduction aux Langages Orientés Objets Qu’est-ce qu’un objet ? Propriétés d'un objet Notion d’héritage et de polymorphisme Les classes en C++ Interface de classe Implantation Constructeur / destructeur Héritage / polymorphisme

C++ : classes

  • Upload
    osborn

  • View
    22

  • Download
    5

Embed Size (px)

DESCRIPTION

C++ : classes. Introduction aux Langages Orientés Objets Qu’est-ce qu’un objet ? Propriétés d'un objet Notion d’héritage et de polymorphisme. Les classes en C++ Interface de classe Implantation Constructeur / destructeur Héritage / polymorphisme. Données membres. Partie privée. - PowerPoint PPT Presentation

Citation preview

Page 1: C++ : classes

C++ : classes

• Introduction aux Langages Orientés Objets – Qu’est-ce qu’un objet ?

– Propriétés d'un objet

– Notion d’héritage et de polymorphisme

• Les classes en C++– Interface de classe

– Implantation

– Constructeur / destructeur

– Héritage / polymorphisme

Page 2: C++ : classes

Langage Orienté Objet : qu’est-ce qu’un objet ?

• Un objet est une entité informatique comprenant :– des données membres (ou champs ou attributs ou variables d’instances)– des fonctions membres (ou méthodes ou routines)

On appelle encapsulation le regroupement des variables et des fonctions au sein d'une même entité.

Ex : un objet vecteur est composé de trois réels et d’opérations telles que la translation, la norme, le produit scalaire …

• L'accès aux données et méthodes peut être réglementé :.

Partie publiqueVision interne

Vision externe

Partie privée

Fonctions membres

Données membres

Page 3: C++ : classes

Objet : exemples (notation UML)

DeuxRoues

m_tailleRoues

m_nbVitesses

m_couleur

m_poidsAccélérer()Freiner()ChangerVitesse()GetCouleur()GetPoids()

Nom de la classe

Données membres ou attributs

Fonctions membres ou méthodes

CompteBancaire

m_numéro

m_solde

m_propriétaireCréditer()Débiter()Fermer()Numéro()Solde()Propriétaire()

Vision interne

Vision externe

Vision interne

Vision externe

Page 4: C++ : classes

Propriétés d’un objet

• Un objet possède un état :L’état correspond à la valeur de ses attributs à un instant donné. Il peut varier au cours du temps.

• Un objet est décrit par une classe :Une classe est un prototype qui définit des attributs et des méthodes communes à tous les objets d'une certaine nature. C’est donc un modèle utilisé pour créer plusieurs objets présentant des caractéristiques communes.

• Un objet possède une identité :Les objets peuvent être distingués grâce à leurs existences inhérentes et non grâce à la description des propriétés qu'ils peuvent avoir. Deux objets peuvent être distincts même si tous leurs attributs ont des valeurs identiques.

Ne pas confondre instance d'objet et classe d'objets Une instance de classe fait référence à une chose préciseUne classe désigne un groupe de choses similaires Ex : Le vélo de mon voisin et le mien sont deux instances de la classe vélo, même s’ils sont

strictement identiques

Page 5: C++ : classes

Notion d’héritage

• L'héritage est un principe propre à la POO qui permet de créer une nouvelle classe à partir d'une classe existante. La classe nouvellement créée, dite classe dérivée, contient les attributs et les méthodes de la classe dont elle dérive, auxquelles s’ajoutent de nouveaux attributs et de nouvelles méthodes propres à la classe dérivée.

• L’héritage permet donc de définir une hiérarchie de classes :– La classe de base est une classe générique.

– Les classes dérivées sont de plus en plus spécialisées

Deux roues

Sans moteur

Scooter

A moteur

MotoVélo Patinette

classe de base ou classe mère ou classe parente

classes dérivées ou classes filles

Mobylette

Page 6: C++ : classes

Notion de polymorphisme

DeuxRoues

m_tailleRoues

m_couleur

m_poids

m_nbVitessesvirtual Accélérer()virtual Freiner()virtual ChangerVitesse()GetCouleur()GetPoids()

Velo

m_typePedaleGetTypePedale()virtual Accélérer()virtual Freiner()virtual ChangerVitesse()

Moto

m_moteur

m_boiteVitesseFairePlein()AllumerClignotant() virtual Accélérer()virtual Freiner()virtual ChangerVitesse()

La fonction Accélérer() n’est pas la même pour un Velo et une Moto. La redéfinition de cette fonction dans chacune des sous-classes entraînera un comportement différent suivant que le DeuxRoues est un Velo ou une Moto.

Une classe dérivée peut fournir une nouvelle définition d’une méthode d'une classe parent car elle peut avoir besoin de réagir différemment à l'appel de cette méthode. Cette redéfinition substituera une méthode à une autre : c’est la spécialisation.La notion de polymorphisme signifie que, la même opération pouvant se comporter différemment sur différentes classes de la hiérarchie, il est possible d'appeler la méthode d'un objet sans se soucier de son type intrinsèque. Ceci permet de faire abstraction des détails des classes spécialisées d'une famille d'objet, en les masquant par une interface commune (qui est la classe de base).

Page 7: C++ : classes

Programmation orientée objet vs programmation séquentielle

• Avantages :– Programmes plus faciles à maintenir

Si on décide de modifier la structure des données dans un programme séquentiel, presque tout le code est à réécrire

– Programmation plus claire : les fonctions sont rattachées à un type de données

– Modularité accrue -> possibilité de ré-utiliser le code

• Inconvénients :– Le programme résultant peut être moins efficace (en termes de taille mémoire et

de rapidité)

Page 8: C++ : classes

class Ellipse

{

Classe : interface

protected :

float m_cX, m_cY;

float m_a, m_b;

public :

void deplace(float dx, float dy);

void zoom(float z);

float surface();

Vision interne

Vision externe

};

C’est la description de la structure interne de la classe

• Visibilité des membres :– public : membres accessibles à tous

– private : membres accessibles à partir de la classe ; accès impossible par l’extérieur

– protected : membres accessibles à partir de la classe et des classes dérivées ; accès impossible par l’extérieur

NB : dans cet exemple, on a choisi de représenter l'ellipse en interne à la classe par les coordonnées de son centre (cX, cY), par son grand axe a et par son petit axe b.

Page 9: C++ : classes

Interface de la classe Ellipse

class Ellipse{ protected :

float m_cX, m_cY;float m_a, m_b;

public :void deplace(float dx, float dy);void zoom(float z);float surface();

};

Classe : implantation

void Ellipse::deplace(float dx, float dy){

m_cX += dx;m_cY += dy;

}

void Ellipse ::zoom(float z){

m_a *= z;m_b *= z;

}

float Ellipse ::surface(){

return 3.14 * m_a * m_b / 4.;}

C’est la définition des fonctions associées

Opérateur de portée

Page 10: C++ : classes

Interface de la classe Ellipseclass Ellipse{ protected :

float m_cX, m_cY;float m_r;

public :void deplace(float dx, float dy);void zoom(float z);float surface();

};

Classe : instanciation

Implantation de la classe Ellipsevoid Ellipse::deplace(float dx, float dy){

m_cX += dx;m_cY += dy;

}void Ellipse::zoom(float z){

m_a *= z;m_b *= z;

}float Ellipse::surface(){

return 3.14 * m_a * m_b / 4.;}

int main(){

Ellipse e;

e.deplace(50, 0);float s = e.surface();e.zoom(1.5);

e.m_cX = 30; // Impossiblee. deplace(20); // Impossible

}

Instancier une classe permet de créer un objet (analogue à une déclaration de variable)

Accès aux membres par le "."

Instanciation statique de l’objet e, e étant une variable de type Ellipse

Page 11: C++ : classes

Organisation (usuelle) des fichiers

#include "ellipse.h"

int main(){

Ellipse e;

e.deplace(50, 0);float s = e.surface();e.zoom(1.5);

return 0;}

#include “ellipse.h”

void Ellipse::deplace(float dx, float dy){

m_cX += dx;m_cY += dy;

}void Ellipse ::zoom(float z){

m_a *= z;m_b *= z;

}float Ellipse :: surface(){

return 3.14 * m_a * m_b / 4.;}

class Ellipse

{

protected :

float m_cX, m_cY;

float m_a, m_b;

public :

void deplace(float dx, float dy);

void zoom(float z);

float surface();

};

• Par convention, l'extension d'un fichier contenant du code C est .cpp, .c++ , .cc , .cxx ou .C• L'extension d'un fichier de déclarations, appelé header, est .h• Par convention, on crée un fichier .cpp et un .h par classe, chaque fichier ayant le nom de la classe en minuscule.

Par convention, les noms de classe commencent par une majuscule, les données membres par _ ou m_, les fonctions membres par une minuscule.

ellipse.h ellipse.cpp main.cpp

Page 12: C++ : classes

Constructeurs de classe

• Le constructeur est une fonction membre qui sert à initialiser les données membres de l’objet

• Systématiquement appelé quand un objet est instancié.• N’a pas de type de retour• Porte le nom de l’objet

• Une même classe peut avoir plusieurs constructeurs

• Constructeurs particuliers :

– constructeur par défaut• Ne contient aucun argument• Automatiquement généré si aucun constructeur n’est défini• A définir explicitement dans le cas contraire

– constructeur de copie• Contient comme argument un objet du même type• Sert à créer des clones d’objets• Automatiquement généré par le compilateur (copie membre à membre) mais pas

toujours satisfaisant

Page 13: C++ : classes

Constructeurs de classe : exemple

#include “ellipse.h”

Ellipse::Ellipse(){

m_cX = m_ cY = 0; m_a = m_b = 1;

}

Ellipse::Ellipse(float x, float y, float a, float b) : m_ cX(x), m_ cY(y), m_a(a), m_b(b)

{}

Ellipse::Ellipse(const Ellipse & e){

m_ cX = e. m_ cX;m_ cY = e. m_ cY;m_a = e.m_a ;m_b = e.m_b;

}

void Ellipse::deplace(float dx, float dy){

m_ cX += dx; m_cY += dy;}

etc …

#include "ellipse.h"

int main(){

Ellipse e1; Ellipse e2(2.5, 6.5, 12, 15); Ellipse e3(e1); // e3 est un clone de e1 Ellipse e4 = e1; // e4 est un clone de e1return 0;

}

class Ellipse{public :

Ellipse(); // Constructeur par défaut Ellipse(float x, float y, float a, float b);

Ellipse(const Ellipse & e);

protected :float m_cX, m_cY;float m_a, m_b;

public :void deplace(float dx, float dy);void zoom(float z) ;float surface() ;

};

ellipse.h ellipse.cpp main.cpp

Page 14: C++ : classes

Destructeur de classe

• Fonction membre systématiquement appelée juste avant la destruction d’un objet

• Porte le nom de la classe et est précédé de ~

• Pas de type de retour

• Pas d’arguments

• Un seul par classe

• Permet de libérer les ressources

#include “ellipse.h”

Ellipse::Ellipse(){

m_cX = m_ cY = 0;m_a = m_b = 1;

}

etc …

Ellipse::~ Ellipse(){

// Libération des ressources}

void Ellipse::deplace(float dx, float dy){

m_cX += dx; m_cY += dy;}

etc …

#include "ellipse.h"

int main(){

Ellipse e;Ellipse* pE = new Ellipse(2.5, 6.5, 12, 15);

delete pE; // appelle le destructeur pour pE

return 0;

// Le destructeur est implicitement appelé pour e.}

class Ellipse{public :

Ellipse(); // Constructeur par défaut Ellipse (float x, float y, float a, float b);

Ellipse(const Ellipse & e);~Ellipse(); // Destructeur

protected :float m_cX, m_cY;float m_a, m_b;

public :void deplace(float dx, float dy);void zoom(float z);float surface();

};

ellipse.h ellipse.cpp prog.cpp

Page 15: C++ : classes

Héritage

L’héritage permet de spécialiser une classe en définissant une relation de type « est une sorte de ».

Cercle

Forme

Ellipse

Carre

Rectangle

Un cercle est un spécialisation d'une ellipse, il en possède les propriétés plus d'autres qui lui sont spécifiques. On dérive donc la classe Cercle de la classe Ellipse.

Page 16: C++ : classes

class Ellipse{public :

Ellipse(); Ellipse (float x, float y, float a, float b);

Ellipse(const Ellipse & e);~Ellipse();

protected :float m_cX, m_cY;float m_a, m_b;

public :void deplace(float dx, float dy);void zoom(float z);float surface();virtual void affiche();

};

Héritage

L’héritage permet de spécialiser une classe en définissant une relation de type « est une sorte de ».

#include “ellipse.h”

class Cercle : public Ellipse{public :

Cercle(); Cercle (float x, float y, float diametre);~ Cercle();

public :virtual void affiche();

};

cercle.h

#include "cercle.h"

int main(){

Cercle c(5, 5, 15);c. affiche();return 0;

}

prog.cppellipse.h

#include <iostream.h>#include “cercle.h”

Cercle::Cercle() : public Ellipse(){}Cercle::Cercle(float x, float y, float diametre) : public Ellipse( x, y, diametre,

diametre){}void Cercle::affiche(){ std::cout << "Cercle de rayon " << m_a / 2 << "\n";}

cercle.cpp

#include <iostream.h>

void Ellipse::affiche(){ std::cout << "Ellipse de grand axe " << m_a;std ::cout << " et de petitt axe " << m_b << "\n";}

ellipse.cpp

Le constructeur de la classe dérivée appelle généralement un des constructeurs de la classe de base.

Autorise la redéfinition de la fonction dans les classes dérivées

Un cercle est un spécialisation d'une ellipse, il en possède les propriétés plus d'autres qui lui sont spécifiques. On dérive donc la classe Cercle de la classe Ellipse.

Page 17: C++ : classes

PolymorphismeUn objet héritant une méthode d'une classe parente peut réagir de façon différente à l'appel de cette méthode.

cercle.cpp

ellipse.cpp

#include " cercle.h"

int main(){

Ellipse e(0, 0, 8.5, 10.2);e.deplace(-1, 1);e.affiche();

Cercle c(-2.5, 2.5, 7,4);c.deplace(0.5, 1.5); c. affiche();

Ellipse *p1; p1 = new Ellipse; p1 ->affiche();

Ellipse *p2; p2 = new Cercle; p2->affiche();

return 0;}

main.cpp

La fonction deplace() n’est pas redéfinie dans la classe Cercle, appelle celle de Ellipse.

La fonction affiche() est redéfinie dans la classe Cercle, appelle celle de Cercle.

ellipse.h cercle.h

Si la fonction affiche() est virtuelle et est redéfinie dans la classe Cercle, appelle celle de Cercle bien que le pointeur soit de type Ellipse. C'est le mécanisme de polymorphisme d'héritage.

class Ellipse{public :

Ellipse(); Ellipse (float x, float y, float a, float b);

Ellipse(const Ellipse & e);~Ellipse();

protected :float m_cX, m_cY;float m_a, m_b;

public :void deplace(float dx, float dy);void zoom(float z);float surface();virtual void affiche();

};

#include <iostream.h>

void Ellipse::affiche(){ std::cout << "Ellipse de grand axe " << m_a;std ::cout << " et de petit axe " << m_b << "\n";}

#include “ellipse.h”

class Cercle : public Ellipse{public :

Cercle(); Cercle (float x, float y, float d);~ Cercle();

public :virtual void affiche();

};

#include “cercle.h”

Cercle::Cercle() : public Ellipse(){}

Cercle::Cercle(float x, float y, float d) : public Ellipse( x, y, d, d)

{}

void Cercle::affiche(){ std::cout << "Cercle de rayon ";

std::cout << m_a / 2 << "\n";}

Appelle la fonction affiche() de la classe Ellipse.

Page 18: C++ : classes

Vocabulaire

• Variable : associe un nom (un symbole) à une valeur qui peut éventuellement varier au cours du temps ; une variable est d’un type donné, défini une fois pour toute (type prédéfini dans le langage ou créé par le développeur).

• Encapsulation : regroupement des variables et des fonctions au sein d'une même entité appelée « classe ».

• Classe : prototype qui définit des attributs et des méthodes communes à tous les objets d'une certaine nature.

• Interface de classe : description de la structure interne de la classe incluant une liste des données membres et le prototype des fonctions membres ; dans un « .h ».

• Implantation de classe : définition (code) des fonctions déclarées dans l’interface de classe ; dans un « .cpp ».

• Instanciation d’un objet : permet de créer un objet d’un type donné ; analogue à une déclaration de variable.

• Héritage : permet de définir une hiérarchie de classe, chaque classe fille héritant des méthodes et des données de son/ses antécédent(s).

• Polymorphisme : deux objets héritant une même méthode d'une classe parente, peuvent réagir de façon différente à l'appel de cette méthode et, à cette fin, redéfinir la méthode. Il est ensuite possible d'appeler la méthode d'un objet sans se soucier de son type intrinsèque.