Rappel C++ du Q1
Opérateurs de comparaison
== égalité
!= inégalité
Opérateurs logiques
< infériorité
&& et logique
> supériorité
|| ou logique
<= infériorité ou égalité
! négation logique
>= supériorité ou égalité
switch (valeur) {
case constante1: bloc1 break;
..
default: blocd break; }
Branchement conditionnel
8
Structures répétitives (les
boucles)
type identificateur[taille]([taille](...));
float vect[100] // déclaration d’un tableau de 100 réels
bool mat[100][50] // déclaration d’une matrice 100X50 booléens
Opérateurs
& : Adresse mémoire d’une variable
* : Valeur de la variable pointée
sizeof : Taille mémoire d’une
variable
12
Allocation dynamique en C++
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.
Une classe dérivée peut fournir une nouvelle définition d’une méthode d'une
classe parente 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.
Velo
DeuxRoues m_typePedale
GetTypePedale()
virtual Accélérer()
m_tailleRoues La fonction Accélérer() n’est pas la
virtual Freiner()
m_couleur même pour un Velo et une Moto. La
virtual ChangerVitesse()
m_poids redéfinition de cette fonction dans
m_nbVitesses chacune des sous-classes entraînera un
Moto comportement différent suivant que le
virtual Accélérer() m_moteur DeuxRoues est un Velo ou une Moto.
virtual Freiner() m_boiteVitesse
virtual ChangerVitesse() FairePlein()
GetCouleur() AllumerClignotant()
GetPoids() virtual Accélérer()
virtual Freiner()
virtual ChangerVitesse()
28
Classe : interface 29
class Ellipse
{
• Visibilité des membres :
Vision protected : – public : membres accessibles à tous
interne float m_cX, m_cY; – private : membres accessibles à
float m_a, m_b; partir de la classe ; accès impossible
par l’extérieur
public : – protected : membres accessibles à
Vision void deplace(float dx, float dy); partir de la classe et des classes
externe void zoom(float z);
dérivées ; accès impossible par
l’extérieur
float surface();
};
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.
Classe : implantation 30
class Ellipse
{
protected : Instancier une classe permet de créer un objet
float m_cX, m_cY; (analogue à une déclaration de variable)
float m_r;
public : Instanciation statique de
void deplace(float dx, float dy);
l’objet e, e étant une
int main() variable de type Ellipse
void zoom(float z);
float surface();
{
}; Ellipse e;
void Ellipse::deplace(float dx, float dy)
{ e.deplace(50, 0);
m_cX += dx;
m_cY += dy;
Accès aux float s = e.surface();
membres
}
par le "." e.zoom(1.5);
void Ellipse::zoom(float z)
{
m_a *= z;
m_b *= z;
e.m_cX = 30; // Impossible
} e. deplace(20); // Impossible
float Ellipse::surface()
{ }
return 3.14 * m_a * m_b / 4.;
}
32
Organisation (usuelle) des fichiers : Les conventions
• 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.
ellipse.h ellipse.cpp main.cpp
#include “ellipse.h” #include "ellipse.h"
class Ellipse
void Ellipse::deplace(float dx, float dy) int main()
{
{ {
protected : m_cX += dx; Ellipse e;
float m_cX, m_cY; m_cY += dy;
float m_a, m_b; } e.deplace(50, 0);
public : void Ellipse ::zoom(float z) float s = e.surface();
{ e.zoom(1.5);
void deplace(float dx, float dy);
m_a *= z;
void zoom(float z); m_b *= z; return 0;
float surface(); } }
}; float Ellipse :: surface()
{
return 3.14 * m_a * m_b / 4.;
}
Par convention, les noms de classe commencent par une majuscule, les données membres par _ ou
m_, les fonctions membres par une minuscule.
33
Constructeurs de classe
o Constructeurs particuliers :
o constructeur par défaut
o Ne contient aucun argument
o Automatiquement généré si aucun constructeur n’est
défini
o A définir explicitement dans le cas contraire
o constructeur de copie
o Contient comme argument un objet du même type
o Sert à créer des clones d’objets
o Automatiquement généré par le compilateur (copie
membre à membre) mais pas toujours satisfaisant
Constructeurs de classe : exemple 35
etc …
Destructeur de classe 36
etc …
38
La notion d’Héritage
Forme
Ellipse Rectangle
Cercle Carre
39
La notion d’héritage
(Inheritance)
ellipse.h cercle.h prog.cpp
class Ellipse #include “ellipse.h” #include "cercle.h"
{
public : class Cercle : public Ellipse int main()
Ellipse(); { {
Ellipse (float x, float y, float a, float b);
public : Cercle c(5, 5, 15);
Ellipse(const Ellipse & e); Cercle(); c. affiche();
~Ellipse();
Cercle (float x, float y, float diametre); return 0;
protected : ~ Cercle(); }
float m_cX, m_cY; public :
float m_a, m_b; virtual void affiche();
};
public :
void deplace(float dx, float dy);
void zoom(float z);
cercle.cpp
float surface(); #include <iostream.h>
Autorise la
virtual void affiche(); Le constructeur de la classe dérivée
redéfinition de #include “cercle.h”
}; appelle généralement un des
la fonction dans
les classes Cercle::Cercle() : public Ellipse() constructeurs de la classe de base.
dérivées {
ellipse.cpp
}
#include <iostream.h> Cercle::Cercle(float x, float y, float diametre) : public Ellipse( x, y, diametre, diametre)
{
void Ellipse::affiche() }
{
void Cercle::affiche()
std::cout << "Ellipse de grand axe " << m_a;
{
std ::cout << " et de petitt axe " << m_b << "\n";
} std::cout << "Cercle de rayon " << m_a / 2 << "\n";
}
Polymorphisme 40
ellipse.h cercle.h
class Ellipse #include “ellipse.h” main.cpp
{
#include " cercle.h"
public : class Cercle : public Ellipse
Ellipse(); {
int main() La fonction deplace() n’est pas
Ellipse (float x, float y, float a, float b); public :
{ redéfinie dans la classe Cercle,
Ellipse(const Ellipse & e); Cercle();
Ellipse e(0, 0, 8.5, 10.2); appelle celle de Ellipse.
~Ellipse(); Cercle (float x, float y, float d);
~ Cercle(); e.deplace(-1, 1); La fonction affiche() est redéfinie
protected : public : e.affiche(); dans la classe Cercle, appelle celle
float m_cX, m_cY; virtual void affiche(); de Cercle.
float m_a, m_b; }; Cercle c(-2.5, 2.5, 7,4);
c.deplace(0.5, 1.5);
public : c. affiche();
void deplace(float dx, float dy); cercle.cpp Appelle la fonction affiche()
void zoom(float z); de la classe Ellipse.
#include “cercle.h” Ellipse *p1;
float surface();
virtual void affiche(); p1 = new Ellipse;
}; Cercle::Cercle() : public Ellipse() p1 ->affiche();
{
} Ellipse *p2; Si la fonction affiche() est
p2 = new Cercle; virtuelle et est redéfinie dans
Cercle::Cercle(float x, float y, float d) : p2->affiche(); la classe Cercle, appelle celle
ellipse.cpp public Ellipse( x, y, d, d)
de Cercle bien que le pointeur
{
#include <iostream.h> return 0; soit de type Ellipse. C'est le
}
} mécanisme de polymorphisme
void Ellipse::affiche() d'héritage.
void Cercle::affiche()
{ {
std::cout << "Ellipse de grand axe " << m_a; std::cout << "Cercle de rayon ";
std ::cout << " et de petit axe " << m_b << "\n"; std::cout << m_a / 2 << "\n";
} }
41
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.