Notions avancées du C++

Slides:



Advertisements
Présentations similaires
Les fonctions A quoi ça sert ?
Advertisements

Spécialisation/généralisation Héritage Polymorphisme
Langages objet Définitions Traduction des méthodes en C++
MySQL I / Présentation. II / Administration et Outils.
(Classes prédéfinies – API Java)
1 La gestion des exceptions C++ Un programme peut rencontrer des conditions exceptionnelles qui risquent de compromettre la poursuite de son exécution.
1 Tableaux des objets C++ si on connaît le nombre dobjets nécessaires davance on peut utiliser des tableau dobjets dans les fonctions dusage class Personne.
C.
Tarak Chaari, Stéphane Frénot, Frédérique Laforest, Frédéric Le-Mouël JAV1 JAV – TD 5 Lhéritage en Java.
Leçon 3 : Héritage IUP 2 Génie Informatique
1 Une introduction à Java IFT 287 (Semaine 1). 2 Java - Historique Développé par Sun Microsystems en 1994 –Inventeur James Gosling (canadien!) Objectif.
Chapitre III Héritage (début)
2ième Classe (Mercredi, 13 Octobre) C++ Intro CSI2572.
Leçon 6 : Structures de données dynamiques IUP 2 Génie Informatique Méthode et Outils pour la Programmation Françoise Greffier.
Les exceptions. Quest ce quune exception ? Une erreur dans le programme Due à un bug ou un cas « anormal » Gestion complète en java : JVM Dans dautre.
Page de garde C++ Le RTTI et les opérateurs de cast Maîtrise dinformatique Février 2002.
Chapitre VII Généricité. POO-L3 H. Fauconnier2 Chapitre VII 1. Principes généraux 2. Types génériques imbriqués 3. Méthodes génériques 4. Types paramètres.
Page de garde C++ Les exceptions Maîtrise dinformatique Février 2002.
Structures de données IFT Abder Alikacem Transtypage Module 1 Département d’informatique et de génie logiciel Édition Septembre 2009.
Un langage de programmation hybride
Miguel Garzon CrUise Lab - SITE. Introduction Data Types and Sizes Constants Logic Operators Type conversions Example.
Contrôle de types Les types en programmation Expressions de types Un contrôleur de types Equivalence de types Conversions de types Généricité.
IFT 6800 Atelier en Technologies d’information
1 IFT 6800 Atelier en Technologies dinformation Le langage de programmation Java chapitre 3 : Classes et Objects.
Cours 8 (18 novembre 2011) exceptions. héritagePOO-L3 H. Fauconnier2 Tableau et héritage Y[] yA=new Y[3]; X[] xA=yA; //ok xA[0]=new Y(); xA[1]=new X();
COURS DE PROGRAMMATION ORIENTEE OBJET :
1 Fonction : surcharge de sélection La surcharge de sélection consiste à implanter plusieurs méthodes de même nom dans une même classe à condition que.
Introduction au C++ héritage / polymorphisme
Héritage Lhéritage permet de spécialiser une classe en définissant une relation de type « est une sorte de ». #include comptebancaire.h class CompteEpargne.
C++ : fonctions et opérateurs
Programme de baccalauréat en informatique Programmation Orientée Objets IFT Thierry EUDE Module 6. Gestion des erreurs et des exceptions : Fonctionnement.
Structures de données IFT-2000
Algorithmique et langage C. Les traitements Comment utiliser les données.
Structures de données IFT-2000 Abder Alikacem Retour sur les listes ordonnées Département dinformatique et de génie logiciel Édition Septembre 2009.
Les Opérateurs Ils régissent toutes les opérations ou transformations sur les valeurs des variables. Opérateur d'affectation Opérateurs arithmétiques Opérateurs.
Une introduction à Java
Héritage Licence Informatique Besançon Méthode et Outils pour la Programmation Françoise Greffier.
Masters IIGLI et IGLII – Programmation générique et conception objet – – Claude Montacié 1 Cours n° 3 Polymorphisme I.
Héritage et composition
2.1 - Historique Chapitre 2 : Introduction au langage C++
9ième Classe (Mardi, 4 novembre) CSI2572. H Nous avons vu comment utiliser les directives #define #ifndef #endif Pour s’assurer de l’inclusion unique.
La notion de type revisitée en POO
Héritage multiple En langage C++, il est possible d’utiliser l’héritage multiple. Il permet de créer des classes dérivées à partir de plusieurs classes.
Cours 9 Exceptions (fin) Généricité. POO-L3 H. Fauconnier2 Chaînage d'exceptions  Une exception peut être causée par une autre.  il peut être utile.
GESTION ET TRAITEMENT DES ERREURS
Algorithmique et langage C. Et me la renvoyer bien sûr… Developpez.com, wiki, siteduzero et autre sont les bienvenus… (les questions sont en orange) C’est.
Argc et argv Utilisation des paramètres de la ligne de commande.
Autres éléments du langage
Cours 7 Classes locales Clonage Divers: tableaux.
Cours C++ Fonctions Surcharge d’opérateurs Passage d’arguments
12/04/ Les exceptions Cours 11 Cours 11.
5ième Classe (Mercredi, 19 octobre) Prog CSI2572.
Les opérateurs L’amitié Les opérateurs Introduction
Les surcharges d'opérateurs
C# de plus près.  Ce sont globalement les mêmes que Java : ◦ Int(int16, int32), float, double, bool,…  Les classe « communes » sont également les mêmes.
8PRO100 Éléments de programmation Les pointeurs de caractères.
Héritage H. Batatia. plan Notion (que signifie l’héritage) Ecriture en java Héritage multiple (interdit) Instanciation (partie propre et partie héritée)
Conception de Programmes - IUT de Paris - 1ère année – Cours 8 – Les entrées/sorties Comment fonctionnent les opérateurs > pour les types élémentaires.
Classe 1 CSI2572 Autres modificateurs de déclaration de variables: & volatile & register & static & auto & extern & const volatile Indique au compilateur.
Cours 4 (14 octobre) Héritage. Chapitre III Héritage.
Conception de Programmes - IUT de Paris - 1ère année – Cours 6 - Les opérateurs L’amitié Les opérateurs –Introduction –Surcharge par fonction.
6ième Classe (Mercredi, 17 novembre) CSI2572
Conception de Programmes - IUT de Paris - 1ère année Cours 2 – Références et passage de paramètres Les Références –Introduction aux références.
Conception de Programmes - IUT de Paris - 1ère année Conception de Programmes Objectifs et organisation du cours Introduction à la P.O.O.
PRO-1027 Programmation Scientifique en C
Structures de données IFT-2000 Abder Alikacem Gestion des exceptions Édition Septembre 2009 Département d’informatique et de génie logiciel Département.
Exception Handling "Unfortunately, it's almost accepted practice to ignore error conditions, as if we're in a state of denial about errors." Bruce Eckel.
Les exceptions Le mécanisme des exceptions est destiné à permettre aux fonctions profondes d'une bibliothèque de notifier la survenue d'une erreur aux.
Transcription de la présentation:

Notions avancées du C++ Downcasting, Héritage multiple, et autres joyeusetés…

Downcasting Transtypage descendant Pas naturel Depuis la classe de base vers la classe dérivée Exemple avec des figures géométriques Parfois nécessaire mais s'il y en a beaucoup : conception à revoir

Downcasting Un cercle est-une figure Un carré est-une figure class Figure { points3D *contour; long nbPointsContour; public : virtual void dessiner()=0; virtual void effacer()=0; virtual Figure *symetrique(/*const Droite &*/); }; class Cercle : public Figure {}; class Carre : public Figure

Downcasting Utilisation de l'opérateur dynamic_cast Syntaxe : int main(int argc, char *argv[]) { Figure *f = new Cercle(…); // avec les bons paramètres Figure *g = f->symetrique(); // traiter g comme un cercle ou un carré ? return 0; } Utilisation de l'opérateur dynamic_cast Syntaxe : dynamic_cast<type_vers_lequel_transtyper>(Expression); Retourne l'expression transtypée.

dynamic_cast<> int main(int argc, char *argv[]) { Figure *f = new Carre(…); // avec les bons paramètres Figure *g = f->symetrique(); Carre *c = dynamic_cast<Carre *>(g); if (c==NULL) // le transtypage a échoué // on pourrait lancer une exception } else c->afficheLeCote(); return 0;

dynamic_cast<> Ne fonctionne qu'avec références et pointeurs : utilisé avec l'héritage et le polymorphisme Vérification effectuée à l'exécution (runtime) Overhead du au mécanisme de vérification dynamic_cast<> retourne NULL si le transtypage n'est pas possible avec des pointeurs Avec des références : exception std::bad_cast lancée : il faut utiliser try…catch !

dynamic_cast<> et références int main(int argc, char *argv[]) { Figure *f = new Carre(…); // avec les bons paramètres Figure *g = f->symetrique(); try Cercle &circ = dynamic_cast<Cercle &>(*g); } catch (std::bad_cast bc) cout << "argh :" << bc.what() << endl; return 0; argh : St8bad_cast

static_cast<> Conversion explicite sans contrôle au runtime Toujours effectué : résultats dangereux Plus rapide que dynamic_cast<> À utiliser quand on connaît exactement le type à obtenir

Dangers de static_cast<> class Cercle : public Figure { long r; public : Cercle():r(2) {} void dessiner() cout << "cercle::dessin()" << endl; } figure *symetrique() // simplifié ici return new Cercle(); long rayon(){return r;} };

Dangers de static_cast<> class Carre : public figure { double _dum; long c; // alignement différent de Cercle public : Carre():c(5) {} void dessiner() cout << "carre::dessiner()" << endl; } figure *symetrique() return new Carre(); long cote() return c; };

Dangers de static_cast<> int main(int argc, char* argv[]) { Figure *fig = new Carre(); Figure *sym = fig->symetrique(); // donc un carré Carre *ca = static_cast<Carre *>(sym); cout << ca->cote() << endl; // allons-y gaiement Cercle *ci = static_cast<Cercle *>(sym); cout << ci->rayon() << endl; return 0; } Ok, c'est le bon type Ca passe à la compilation car c'est du static_cast 5 4064344

Explication 8 octets pour un double sym 4octets pour un long ca Figure *sym = fig->symetrique(); Carre *ca = static_cast<Carre *>(sym); cout << ca->cote() << endl; Cercle *ci = static_cast<Cercle *>(sym); cout << ci->rayon() << endl; ca Rappel : dans Carre : un double, un long dans Cercle : un long ci Ce que "voit" ci ci 4 octets pour un long

Héritage multiple et virtuel Une classe peut hériter de plusieurs classes Parfois nécessaire Mais attention au losange ! Classe A Classe B Classe C Classe D

Membres de A Par héritage, les membres de A sont présents dans B et C, et donc dans D, mais…plusieurs fois ! Un attribut peut donc être ambigu ! On peut : Lever l'ambiguïté en qualifiant l'attribut Utiliser l'héritage virtuel

Exemple class A { protected : string s; public : A(const string &_s="A"):s(_s){cout << "A::A(" << s<<")"<< endl;} }; class B : public A public : B(const string &_s="B"):A(_s){cout << "B::B(" << s<<")"<< endl;} void f() {cout << s << endl;} class C : public A public : C(const string &_s="C"):A(_s){cout << "C::C(" << s<<")"<< endl;}

Exemple Indiquer de quelle classe il s'agit : A, B ou C ? class D : public B, public C { public : D():B("DB"),C("DC"){cout << "D::D(" << s <<")"<< endl;} void f() cout << s << endl; } }; Indiquer de quelle classe il s'agit : A, B ou C ? A::s Reference to 's' is ambiguous 'A' is an ambiguous base of 'D'

Exemple : choix de B Pourquoi celui-là ? A::A(DB) B::B(DB) A::A(DC) class D : public B, public C { public : D():B("DB"),C("DC"){cout << "D::D(" << B::s <<")"<< endl;} void f() cout << B::s << endl; } }; Pourquoi celui-là ? dans main() : D d; A::A(DB) B::B(DB) A::A(DC) C::C(DC) D::D(DB)

Héritage Virtuel class B : virtual public A {…}; class C : virtual public A {…}; Ainsi, les membres de A ne sont plus dupliqués dans D ! D d; Mais il y a un prix à payer ! A::A(A) B::B(A) C::C(A) D::D(A)

Héritage Virtuel class B : virtual public A {…}; class C : virtual public A {…}; Ainsi, les membres de A ne sont plus dupliqués dans D ! D d; Mais il y a un prix à payer ! A::A(A) B::B(A) C::C(A) D::D(A) On ne peut plus faire de downcasting statique avec un héritage virtuel ! On doit utiliser dynamic_cast<>

Les foncteurs Objet et fonction en même temps Par surcharge de l'opérateur () : accepte plusieurs paramètres Permet de réaliser des pointeurs de fonction Passe des paramètres à l'objet

Foncteurs simple Exemple à vertu pédagogique Dans main() : Affiche 3… class X { public : void operator()(long p) cout << p << endl; } }; Dans main() : X x; x(3); Affiche 3…

Foncteurs moins simple (mais mieux) class action { char _optype; public : action(const char op='+'):_optype(op) {} int operator()(int a, int b) switch(_optype) case '+' : return a+b; case '-' : return a-b; default : return 0; } }; Le constructeur L'opérateur ()

Foncteurs moins simple (mais mieux) int main(int argc, char *argv[]) { action a; action b('-'); int x = a(4,3); cout << x << " et " << b(x,a(1,1)) << endl; return 0; }

Foncteur carrément moins simple (mais carrément mieux) template<class T> class action { char _optype; public : action(const char op='+'):_optype(op) {} T operator()(T a, T b) swith(_optype) case '+' : return a+b; case '-' : return a-b; default : return 0; } }; Seule contrainte : T doit implémenter operator+, operator-

Foncteur carrément moins simple (mais carrément mieux) int main(int argc, char *argv[]) { action<int> a; action<int> b('-'); action<string> c; int x = a(4,3); cout << x << " et " << b(x,a(1,1)) << endl; cout << c("hello ", "world++"); return 0; } On peut même étendre avec un troisième paramètre indiquant l'opération à effectuer !

Foncteur et STL Parcours de conteneur avec un itérateur : boucle for Appliquer une fonction (un traitement) à tous les objets stockés dans un conteneur : fonction for_each (du namespace std) std::for_each(début de conteneur, fin de conteneur, opération); Opération est une fonction qui sera appelée, avec en paramètre un objet issu du conteneur

Foncteur et STL Applique la fonction f à tous les objets string de vec void f(string &s) { cout << s << endl; } int main(int argc, char *argv[]) vector<string> vec; vec.push_back("un"); vec.push_back("deux"); vec.push_back("trois"); std::for_each(vec.begin(), vec.end(), f); return 0; Applique la fonction f à tous les objets string de vec

Foncteur et STL On voudrait diriger ces objets vers un flux quelconque (std::cout ou fichier). La fonction f aurait deux paramètres : pas compatible avec for_each : on utilise un foncteur ! class StringWriter { ostream& _flow; public : StringWriter(ostream& fl):_flow(fl) {} void operator()(const string &s) _flow << s; } };

Foncteur et STL On associe le flot à traiter en appelant le constructeur de StringWriter, le paramètre est traité par l'opérateur() de la classe StringWriter int main(int argc, char *argv[]) { vector<string> vec; vec.push_back("un"); vec.push_back("deux"); vec.push_back("trois"); std::for_each(vec.begin(), vec.end(), StringWriter(std::cout)); return 0; } Paramètre du constructeur, pas de l'appel à l'opérateur ()

Foncteur et STL Extension de la classe Writer class AnyWriter { ostream& _flow; public : AnyWriter(ostream& fl):_flow(fl) {} template<class T> void operator()(const T &towrite) _flow << towrite; } };