Upload
others
View
5
Download
0
Embed Size (px)
Citation preview
Algorithmique, C++
Recollement d'images
Introduction à C++Deuxième partie
Héritage, généricité
Plan de la séance
Compléments sur les classes
Héritage
Généricité
Autoréférence : this Mot-clé this : pointeur sur l'objet
considéré Exemple :
Point& Point::copie(const Point& P){if (this == &P) return *this;
// pas de recopie de soi-même :
// this = objet auquel on applique copie()
_x = P._x; // après return <=> else
this->_y = P._y; // eq. à _y = P._y;return *this;
}
Méthodes inline Les méthodes définies à l'intérieur de la classe
(méthodes inlines) : code recopié (si possible) à chaque appel, accélérer l'exécution (pas d'appel de fonction)
Les fonctions membres définies à l'extérieur de la classe (avec ::) peuvent aussi être inlinées :
inline int Point::abscisse() const {…}
Le compilateur ESSAIERA de recopier le code si celui-ci n'est pas trop important
Attributs et méthodes statiques
Attributs statiques d'une classe :
partagés par tous les objets
Méthodes statiques : appelées par la classe (et non par un
objet de la classe) : peut accéder uniquement aux attributs
statiques concept : fonction indépendante des objets
pas besoin d'instancier un objet
Exempleclass Repere {
static Point _orig;// le même pour tous les objets de la classe
public:
static void change_orig (const Point& p) { _orig = P; }
};
main () {
Point M(3,4); Repere R1;
Repere::change_orig(M); // pas R1.change_orig(M);
}
Méthodes et classes amies
Méthodes externes ayant le droit de manipuler attributs et méthodes privés ou protégés d'un objet
Mot-clé friend
Classe amie : déclarée « friend » à l'intérieur d'une classe, définie en dehors, mêmes droits que les méthodes
Exemple class Point {
friend std::ostream& operator<<(std::ostream&, const Point&);
friend class PointSet;
private:
double _x; double _y;
};
std::ostream& operator<<(std::ostream& o, const Point& p) {
o << “(“ << p._x << “,” << p._y << “)”;
return o;
}
class PointSet {
Init_Point(Point* p) {p->_x = 0.0; p->_y = 0.0;}
}
Surcharge des opérateurs De base : ensemble d'opérateurs pour les types
intégrés : int + int, bool == bool, …
L'utilisateur peut surcharger ces opérateurs pour les types qu'il définit.
Opérateurs redéfinissables (liste non exhaustive) :
+ - * / % += ++ == && || << >> [] () new new[] delete delete[]
Attention à la précédence !
Exemple : classe Complexe
class Complexe {
float _re, _im;
public:
Complexe& operator+= (Complexe x){
_re += x._re;_im += x.im;return *this;
}
…
};
Plan de la séance
Quelques compléments sur les classes
Héritage
Généricité
Héritage/dérivation Définition d'une nouvelle classe à partir
d'une classe existante (appelée classe mère)
Hiérarchie de classes
Vocabulaire : la classe B dérive de la classe A <=> tout objet de type B hérite des attributs et des méthodes d'un objet de type A
Différence avec Java : héritage multiple possible
une classe C peut dériver de A et de B
Accès aux attributs et méthodes de la classe mère
class X : public A { … };
La protection des membres de la classe A est inchangée dans la classe X.
class Y : protected B { … };
Les membres public et protected de B sont protected dans Y. Les classes dérivées de Y ont accès aux membres de B.
class Z : private C { … };
Les membres public et protected de C sont private dans Z. Les classes dérivées de Z n’ont plus accès aux membres de C.
Création / Destruction Les constructeurs de la/des classe(s)
mère(s) ne sont pas hérités :
Les appeler explicitement pour construire les attributs hérités
On peut spécifier des paramètres à ces constructeurs si on le souhaite ou si besoin est
Appel aux destructeurs dans l'ordre inverse :
destructeur(s) de la/des classe(s) mère(s) après celui de la classe fille
Exempleclass DPoint : public Point {
protected:
int id;
public:
Dpoint(double x,double y,int i) : Point(x,y), id(i) {}
Dpoint(const Dpoint& d) : Point(d), id(d.id) {}
// Constructeur de recopie
…
// Pas besoin d'écrire ~Dpoint(): ~Point() sera appelé
};
Redéfinition des méthodes La méthode d'une classe dérivée masque
la méthode de la classe mèreclass Mere {
public: void f() {…} };
class Fille: public Mere {
public: void f() {…} };
Utilisation :void main() {
Fille Fi; Fi.f(); // appel à Fille::f() Fi.Mere::f() // appel à Mere::f()
};
Liaisons statiques Sélection d'un membre (attribut ou méthode) :
déterminé statiquement à la compilation en fonction du type du pointeur ou de référence
Exemple :class Mere {
public: int f() {…} }; class Fille : public Mere {
public: int f() {…} }; void main() { Fille Fi; Mere *ptr = &Fi; int i = ptr->f() ; // Mere::f() (liaison statique)
};
Liaisons dynamiques : fonctions virtuelles
Pour que la fonction appelée soit en rapport avec le type de l'objet pointé au moment de l'appel
Mot-clé virtual Exemple :
class Mere {
public: virtual int f() {…} }; class Fille : public Mere {
public: int f() {…} }; void main() { Fille Fi; Mere *ptr = &Fi; int i = ptr->f() ; // Fille::f() (liaison dynamique) };
Fonctions virtuelles pures Définition d'une fonction sans donner son
implantation (laissée aux classes dérivées) class Mere {
public: virtual int f() = 0; };
class Fille : public Mere {public: int f() {…} };
Une classe ayant une fonction membre virtuelle pure (classe abstraite) ne peut pas être instanciée, => sim. interface Java Pointeur vers classe abstraite : OK
Héritage multiple
Une classe peut dériver de plusieurs classes mères, avec des accès différents aux attributs et méthodes de celles-ci
Les classes mères moins prioritaires peuvent être indiquées avec le mot-clé virtual
Syntaxe :class A {…};
class B {…};
class C: public virtual A, private B {…};
Gestion des ambiguïtés Utiliser :: Exemple :class Mere1 {
public: int f() {…} };class Mere2 {
public: int f() {…} };class Fille: public Mere1, Mere2 {…};void main () { Fille Fi; int i1 = Fi.f(); // Illégal car ambigu int i2 = Fi.Mere1::f(); // OK};
Plan de la séance
Quelques compléments sur les classes
Héritage
Généricité
Polymorphisme et généricité
Polymorphisme = autoriser le même code à être utilisé avec différents types/classes Méthodes virtuelles héritées
(polymorphisme par dérivation) Programmation générique :
fonctions indépendantes du type (voire du nombre) de leurs arguments
→ augmentation du niveau d'abstraction
Généricité : les modèles Canevas décrivant une famille de
composants : famille de fonctions famille de types famille de membres …
Les types peuvent devenir des paramètres Mot-clé template
Modèles de fonctions : exemple 1
template<int N>void f() {
float tab[N]; // N ne sera fixé qu'à la compilation
for (int i=0; i< N; i++) cin >> tab[i]; }
L'instanciation void (*pf)()=f<100>; conduit lecompilateur à générer le code :
void f() {
float tab[100]; for (int i=0; i< 100; i++) cin >> tab[i]; }
L'instanciation f<100>() génère le même code et appelle la fonction
Modèles de fonctions : exemple 2
template<class T>
void f(const T& t) { … }
L'instanciation :int i; f(i); // ! <int> pas nécessaire
conduit le compilateur à générer le code :
void f(const int& t) { … }
et appelle la fonction avec i en paramètre
Modèles de classe :exemple 1
template <typename T, int taille_max = 200>class pile { private: T* la_pile; public: typedef T value_type; pile() { la_pile = new T[taille_max]; } ~pile() { delete [] la_pile; }};void main() { typedef pile< char, 26 > Alphabet; Alphabet p; // Pile de 26 caractères};
Modèles de classe :exemple 2
template <class A, class B>class paire {
public: A a; B b; paire (A aa, B bb) : a(aa), b(bb) {} bool operator==(paire p) { return a==p.a && b==p.b; }};void main() {
paire<int, char> p1(1,'A') ;};
typename Indique que le mot suivant doit être considéré
comme un type : template <typename T> Equivalent de class dans un template Egalement utile lorsque le type n'est pas
instancié :template <class T>
class pile {
typedef typename T::value_type T_values;
// T pas instancié => indique que T::value_type
// est bien un type
};
Spécialisation de modèle On peut donner une implantation
particulière pour un type particulier :template <class T>
T min(T a, T b){return (a<b) ? a : b;
}
=> spécialisation pour le type char* :template<>
char* min<char*> (char *a, char *b) {return strcmp(a,b)<0 ? a : b ;
}