POO_CH5 - dept-info.labri.fr

Transcription

POO_CH5 - dept-info.labri.fr
Classes abstraites
Classe abstraite :
(1) Elle sert de prototype à toutes les classes
dérivées
(2) Elle n’a pas d’objets instanciant cette
classe.
(3) Elle contient au moins une fonction
virtuelle pure
virtual Type f()=0;
virtual TypeAutre p(TypeArg arg)=0;
13/01/2013
1
Classes Abstraites
Forme
Point
Rectangle
Cercle
Sphère
2
1
Classe abstraite (1)
class Forme{
protected:
double x;
double y;
public:
//Pas de constructeur
virtual void affiche()=0;
void deplace(double dx,double
dy){x=x+dx;y=y+dy;}
};
class Point:public Forme{
public:
Point(double _x=0.0, double
_y=0.0){x=_x;y=_y;};
#include <iostream.h>
#include "GeometrieAbstr.hpp"
int main(){
Point p(3.0,5.0);
Point * pP=&p;
Cercle C(6.0,7.0,8.0);
Cercle *pC=&C;
pP->affiche();
pC->affiche();
pC->deplace(0.5,0.5);
pC->affiche();
return 0;
}
virtual void affiche() {cout<<"Affiche point x="<<x<<"
y="<<y<<endl;}
Méthode virtuelle pure
};
class Cercle : public Point{
protected:
double rayon;
public:
Cercle(double _x, double _y, double
_r):Point(_x,_y){rayon=_r;}
virtual void affiche(){cout<<"Afficne Cercle
x="<<x<<" y="<<y<<" r="<<rayon<<endl;}
Méthode concrète
3
};…
Classe abstraite (2)
class Forme{
protected:
double x;
double y;
public:
//Constructeur
Forme(double _x=0.0, double
_y=0.0){x=_x;y=_y;}
virtual void affiche()=0;
void deplace(double dx,double
dy){x=x+dx;y=y+dy;}
};
class Point:public Forme{
public:
Point(double _x=0.0, double _y=0.0):Forme(_x,_y){}
virtual void affiche() {cout<<"Affiche point x="<<x<<"
y="<<y<<endl;}
#include <iostream.h>
#include "GeometrieAbstr.hpp"
int main(){
Point p(3.0,5.0);
Point * pP=&p;
Cercle C(6.0,7.0,8.0);
Cercle *pC=&C;
pP->affiche();
pC->affiche();
pC->deplace(0.5,0.5);
pC->affiche();
return 0;
}
Résultats?
};
class Cercle : public Point{
protected:
double rayon;
public:
Cercle(double _x, double _y, double
_r):Point(_x,_y){rayon=_r;}
virtual void affiche(){cout<<"Afficne Cercle
x="<<x<<" y="<<y<<" r="<<rayon<<endl;}
};…
4
2
Classe abstraite (2)
class Forme{
protected:
double x;
double y;
public:
//Constructeur
Forme(double _x=0.0, double
_y=0.0){x=_x;y=_y;}
virtual void affiche()=0;
void deplace(double dx,double
dy){x=x+dx;y=y+dy;}
};
class Point:public Forme{
public:
Point(double _x=0.0, double _y=0.0):Forme(_x,_y){}
virtual void affiche() {cout<<"Affiche point x="<<x<<"
y="<<y<<endl;}
};
class Cercle : public Point{
protected:
double rayon;
public:
Cercle(double _x, double _y, double
_r):Point(_x,_y){rayon=_r;}
virtual void affiche(){cout<<"Afficne Cercle
x="<<x<<" y="<<y<<" r="<<rayon<<endl;}
#include <iostream.h>
#include "GeometrieAbstr.hpp"
int main(){
Forme f(0.1,0.1);// Objet d’une classe
abstraite
Point p(3.0,5.0);
Point * pP=&p;
…
}
Forme' : cannot instantiate abstract class due to following
members:
d:\pédagogiebx\poo\geometrieabstr.hpp(1) : see declaration
of 'Forme'
D:\PédagogieBx\POO\GeometrieAbstr.cpp(4) : warning C4259:
'void __thiscall Forme::affiche(void)' : pure virtual function was not
defined
d:\pédagogiebx\poo\geometrieabstr.hpp(8) : see declaration
of 'affiche'
D:\PédagogieBx\POO\GeometrieAbstr.cpp(4) : error C2259:
'Forme' : cannot instantiate abstract class due to following
members:
d:\pédagogiebx\poo\geometrieabstr.hpp(1) : see declaration
of 'Forme'
D:\PédagogieBx\POO\GeometrieAbstr.cpp(4) : warning C4259:
'void __thiscall Forme::affiche(void)' : pure virtual function was not
defined
5
};…
Classe abstraite – méthodes virtuelles
Une fonction déclarée virtuelle dans une
classe de base doit être
-redéfinie (avec les mêmes arguments!) dans
la classe dérivée ou
-elle reste virtuelle pure dans la classe
dérivée
En Java – la définition des classes abstraites
par le qualificatif « abstract »
13/01/2013
6
3
Classes Abstraites(3).
Forme
Cercle
Rectangle
7
Classe abstraite (3). Methode concrete
utilise des méthodes virtuelles
class Forme{
protected:
double x;
double y;//centre de gravité de la Forme dans un
repère
public:
Forme(double _x=0.0, double
_y=0.0){x=_x;y=_y;}
//Pas de constructeur!
virtual void affiche()=0;
virtual double surface()=0;
virtual double perimetre()=0;
double facteur_compacite(){ return
perimetre()/surface();}
};
class Cercle : public Forme{
protected:
double rayon;
public:
Cercle(double _x, double _y, double
_r):Forme(_x,_y){rayon=_r;}
virtual void affiche(){cout<<"Afficne Cercle
x="<<x<<" y="<<y<<" r="<<rayon<<endl;}
double surface(){return 3.1416*rayon*rayon;}
//Pas de mot-clé virtual!
double perimetre(){return 2*3.1416*rayon;}
};//La
suite est à droite!
class Rectangle : public Forme{
protected:
double a,b;
public:
Rectangle (double _x, double _y, double _a, double
_b):Forme(_x,_y){a=_a;b=_b;}
virtual void affiche(){cout<<"Affiche
Rectangle"<<" x="<<x<<" y="<<y<<" a="<<a<<"b
="<<b<<endl;}
double surface(){return a*b;} //Pas de mot-clé
virtual!
double perimetre(){return 2*(a+b);}
};
Fichier Geomertie VirtualUse.CPP
#include <iostream.h>
#include "GeometrieVirtualUse.hpp"
int main(){
Cercle C(6.0,7.0,8.0);
Rectangle R(2.0,3.0,4.0,5.0);
C.affiche();
R.affiche();
cout<<"Cercle fc=
"<<C.facteur_compacite()<<endl;
cout<<"Rectangle fc=
"<<R.facteur_compacite()<<endl;
return 0;
}
8
4
Amitié en C++ : Fonctions et Classes
Amies
Hors l’héritage il peut être nécessaire de prévoir les
passerelles entre les classes
Fonctions-amies : peuvent accéder aux informations
encapsulées.
Typologie :
fonction indépendante, amie d’une classe,
fonction membre d’une classe, amie d’une autre classe,
fonction amie de plusieurs classes,
Toutes les fonctions membres d’une classe, amies d’une
autre classe
13/01/2013
9
Amie indépendante d’une classe
class Point{
private:
#include <iostream.h>
#include "FonctionAmie.hpp"
double x;
double y;
public:
Point(double _x=0.0, double
_y=0.0){x=_x;y=_y;}
void affiche(){cout<<"Je suis un point
x="<<x<<" y="<<y<<endl;}
//déclaration fonction amie indépendante
friend int coincide (Point
p,Point q);
};
Intérêt : accès aux données privées des objets de la
classe
Passage des objets est réalisé par valeur,
Il est possible par référence
int coincide (Point p, Point q)
{return (int)((p.x==q.x)&&(p.y==q.y));}
int main(){
Point P(0.1,0.2);
Point Q(0.1,0.2);
if(coincide(P,Q))
cout<<"P et Q coincident test par leur amie "<<endl;
else
cout<<"P et Q sont
différents - test pa leur amie"<<endl;
return 0;
}
Résultat
P et Q coincident – test par leur amie
“Bienfaiteur” des malheureux
10
5
Fonction amie de plusieurs classes
class Heure;
class Date{
private:
#include <iostream.h>
#include "FonctionAmieCL.hpp"
unsigned j,m,a;
public:
Date(unsigned _j, unsigned _m, unsigned
_a){j=_j;m=_m;a=_a;}
friend void affiche_moment(Date,Heure);
//déclaration fonction amie
void affiche_moment(Date _d,Heure _h){
cout<<"Date : j="<<_d.j<<"
m="<<_d.m<<" a de grace ="<<_d.a<<endl;
cout<<"Heure : h="<<_h.h<<"
min="<<_h.m<<" sec="<<_h.s<<endl;
}
};
int main(){
Date Aujourdhui(25,2,2004);
Heure Maintenant(16,15,50);
affiche_moment(Aujourdhui, Maintenant);
return 0;
class Heure{
private:
unsigned h,m,s;
public:
Heure(unsigned _h, unsigned _m,
unsigned _s){h=_h;m=_m;s=_s;}
friend void affiche_moment(Date,Heure);
};
}
“Cousine Betty”
11
Classes -amies
Toutes les fonctions d’une classe sont des amies
d’une autre classe
Pourquoi(?): elles peuvent accéder aux données
privées d’une autre classe
Héritage et amitié (?)
13/01/2013
12
6
Classes-amies
class Distance;
class Point{
friend class Distance;
private:
double x;
double y;//centre de gravité de la Forme
dans un repère
public:
Point(double _x=0.0, double
_y=0.0){x=_x;y=_y;}
void affiche(){cout<<"Je suis un point
x="<<x<<" y="<<y<<endl;}
#include <iostream.h>
#include "FonctionAmie.hpp"
int main(){
Point P(1.1,2.2);
Point Q(3.1,2.2);
Distance PQ(P,Q);
PQ.affiche();
return 0;
}
« Thibault et Fontanin »
};
class Distance{
private:
double d;
public:
Distance(double _d){d=_d;}
Distance(Point P, Point Q)
{d=((P.x-Q.x)*(P.x-Q.x)+(P.y-Q.y)*(P.yQ.y));}
void
affiche(){cout<<"Distance="<<d<<endl;}
13
Héritage et amitié
class Father;
class Mother{
friend class Father;
protected:
int a;
public:
class Son: public Father{
protected:
int b;
public:
Son(int _a, int _b):Father(_a){b=_b;}
};
Mother(int _a){a=_a;}
};
class Dotter:public Mother{
protected:
int b;
public:
Dotter(int _a, int _b):Mother(_a){b=_b;}
};
class Father{
protected:
int a;
#include<iostream.h>
#include "HeritageAmitie.h"
int main(){
Father f(2);
Son s(3,4);
Mother m(2);
Dotter d(5,6);
f.aff(m);
f.aff(d);
return 0;
}
public:
Father(int _a){a=_a;}
void aff(Mother wife){cout<<"Affichage de
l'epouse a= "<<wife.a<<endl;}
void aff(Dotter girlfriend){cout<<"Affichage de
copine a="<<girlfriend.a<<endl;}
};
//La suite est à gauche
On peut acceder à la partie déclaré
en amitié!
14
7
Héritage et amitié
class Father;
class Mother{
friend class Father;
protected:
int a;
public:
Mother(int _a){a=_a;}
};
class Son: public Father{
protected:
int b;
public:
Son(int _a, int _b):Father(_a){b=_b;}
void aff(Mother M){cout<<"M.a="<<M.a<<endl;}
//cannot access protected member declared in
class 'Mother'
};
class Dotter:public Mother{
protected:
int b;
public:
Dotter(int _a, int _b):Mother(_a){b=_b;}
};
class Father{
protected:
int a;
public:
Father(int _a){a=_a;}
void aff(Mother wife){cout<<"Affichage de
l'epouse a= "<<wife.a<<endl;}
void aff(Dotter girlfriend){cout<<"Affichage de
copine a="<<girlfriend.a<<endl;}
void aff(Dotter girlfriend){cout<<"Affichage de copine
b="<<girlfriend.b<<endl;}//Erreur
};
//La suite est à gauche
#include<iostream.h>
#include "HeritageAmitie.h"
int main(){
Father f(2);
Son s(3,4);
Mother m(2);
Dotter d(5,6);
f.aff(m);
f.aff(d);
return 0;
}
On ne peut pas hériter un ami!
On ne peut pas toucher à la partie
15
non-partagée
8

Documents pareils