IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Type Erasure : marier la POO et la Programmation Générique [Tutoriel]


Sujet :

Langage C++

  1. #21
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Citation Envoyé par vandamme Voir le message
    Merci bcp pour tes reponses.

    Mais la reponse a la 1ere question ..... je comprends pas.
    Le ooops aie est pour moi ou pour toi ?
    Il faut effectivement enlever le wdiget::

  2. #22
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    N'est-ce pas déjà trop tard de toute façon, pour appeler une fonction virtuelle?

    À moins que cette restriction ne s'applique qu'aux constructeurs et pas au destructeur? Je ne sais jamais...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #23
    Membre confirmé

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 162
    Points : 545
    Points
    545
    Par défaut
    Non cela ne s'applique qu'aux constructeurs

  4. #24
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par vandamme Voir le message
    Non cela ne s'applique qu'aux constructeurs
    Penser en C++
    Citation Envoyé par Bruce Eckel
    Dans un destructeur, seule, la version “locale” de la fonction membre est appelée ; le mécanisme virtuel est ignoré.

  5. #25
    Membre confirmé

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 162
    Points : 545
    Points
    545
    Par défaut
    Oui desole pour l'erreur.
    Je voulais bien sur dire que la restriction pour l'appel des fonctions virtuelles ne s'applique qu'aux destructeurs.

  6. #26
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par vandamme Voir le message
    Oui desole pour l'erreur.
    Je voulais bien sur dire que la restriction pour l'appel des fonctions virtuelles ne s'applique qu'aux destructeurs.
    Perdu encore, non?

    Je sais que ça s'applique aux constructeurs.† Donc, ça s'applique bien aux deux, c'est ça?

    †sauf pour les types managés en .Net, pour des raisons liées à l'implémentation du CLR.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #27
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Je modifierai le code pour résoudre ce soucis, bien que ça ne soit pas le centre de l'article

  8. #28
    Membre confirmé

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 162
    Points : 545
    Points
    545
    Par défaut
    Oui perdu !!!!

    Mais j'aurais appris qqchose !!!

  9. #29
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Points : 588
    Points
    588
    Par défaut
    Désolé de faire un petit remontage de post, mais j'aimerais répondre à l'un des interrogations de escafr, vu qu'il n'y a pas eu de réponse à priori...

    Citation Envoyé par escafr Voir le message
    - Si je veux rendre un widget non clickable en clickable? Je fais comment?
    Comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    #include <cstdlib>
    #include <iostream>
     
    struct NonClickable;
     
    struct Clickable
    {
    	Clickable()
    	{
    	}
     
    	Clickable( const NonClickable& )
    	{
    	}
    	void tell()
    	{
    		std::cout << "Clickable policy" << std::endl;
    	}
     
    	void click()
    	{
    		std::cout << "Clickable::clicked()" << std::endl;
    	}
    };
     
    struct NonClickable
    {
    	NonClickable()
    	{
    	}
     
    	NonClickable( const Clickable& )
    	{
    	}
     
    	void tell()
    	{
    		std::cout << "Nonclickable policy" << std::endl;
    	}
    	// pas de click();
    };
     
    template
    <
    	class ClickPolicy
    >
    class Widget :
    	public ClickPolicy
    {
    public:
    	Widget(int id) :
    		id_(id)
    	{
    		ClickPolicy::tell();
    	}
     
    	template
    	<
    		class OtherClickPolicy
    	>
    	Widget( const Widget< OtherClickPolicy >& o ) :
    		ClickPolicy( o ),
    		id_( o.id_ )
    	{
    		ClickPolicy::tell();
    	}
     
    	int id_;
    };
     
    int main( int argc, char* argv[] )
    {
    	Widget<Clickable> clickableWidget(1);
    	clickableWidget.click();
     
    	Widget<NonClickable> nonClickableWidget( clickableWidget );
    	// nonClickableWidget.click(); compilera pas.
     
    	// et l'inverse
    	Widget< Clickable > clickableWidgetAgain( nonClickableWidget );
    	clickableWidgetAgain.click();
     
    	return 0;
    }
    Citation Envoyé par escafr
    - Si je veux ajouter une politique, mettons DragNDrop, je dois modifier toute ma classe widget, je ne trouve pas ça très souple ni paramétrable.
    En réalité, tu ne dois modifier QUE ta classe Widget, ce qui est en fait quelque chose de naturel, vu que c'est l'hôte de la politique que tu veux ajouter.

    Rien ne t'empêche de définir des politiques par défaut pour ta classe hôte, en mettant en premier ceux qui sont le plus modifiés. Les nouvelles politiques arrivant naturellement sur les dernières places, et possèdant leur comportement par défaut (quitte à ce que ça soit: "ne rien faire"), ça n'interfèrera pas avec le code existant.

    Le nouveau code viendra s'installer naturellement, sans intérférer ou modifier le code existant, ce qui est ce qu'on recherche.

    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    struct RectangleDraw
    {
    	void tell()
    	{
    		std::cout << "RectangleDraw policy" << std::endl;
    	}
     
    	void draw()
    	{
    		std::cout << " _________ " << std::endl;
    		std::cout << "|         |" << std::endl;
    		std::cout << "|_________|" << std::endl;
    	}
    };
     
    struct SquareDraw
    {
    	void tell()
    	{
    		std::cout << "SquareDraw policy" << std::endl;
    	}
     
    	void draw()
    	{
    		std::cout << " _____ " << std::endl;
    		std::cout << "|     |" << std::endl;
    		std::cout << "|     |" << std::endl;
    		std::cout << "|_____|" << std::endl;
    	}
    };
     
    struct NoDraw
    {
    	void tell()
    	{
    		std::cout << "NoDraw policy" << std::endl;
    	}
    };
     
    template
    <
    	class ClickPolicy = NonClickable,
    	class DrawingPolicy = NoDraw
    >
    class Widget :
    	public ClickPolicy,
    	public DrawingPolicy
    {
    public:
    	Widget(int id) :
    		id_(id)
    	{
    		policies_tell();
    	}
     
    	template
    	<
    		class OtherClickPolicy,
    		class OtherDrawPolicy
    	>
    	Widget( const Widget< OtherClickPolicy, OtherDrawPolicy >& o ) :
    		ClickPolicy( o ),
    		id_( o.id_ )
    	{
    		policies_tell();
    	}
     
    	void policies_tell()
    	{
    		DrawingPolicy::tell();
    		ClickPolicy::tell();
    	}
     
    	int id_;
    };
     
    int main( int argc, char* argv[] )
    {
    	Widget<> wdg(1);	
    	// wdg.click() ne compilera pas
    	// wdg.draw() compilera pas
     
    	// nouveau widget
    	Widget< Clickable, RectangleDraw > crWdg(2);
    	crWdg.click();
    	crWdg.draw();
     
    	return 0;
    }
    Citation Envoyé par escafr
    et devoir déclarer un typedef pour rendre "utilisable" la classe..
    on va finir avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    typedef widget_impl <
        NonResizable,
        NonClickAware,
        ReadOnlyText,
        SquareDraw
          > widget_NrNcaRotS;
    ...
    etc etc pour chaque possibilité de widget
    En réalité, c'est justement l'inverse de l'effet recherché. Préfères-tu écrire une hiérarchie de N^2 classes à multiples héritages ou N classes sans redondance ?

    L'héritage pure/multiple, dans ce cas-ci, va nous emmener dans pire que ce qu'on a: au lieu d'avoir un typage fort, on va quasiment pas en avoir, ou du moins pas de controle sur ce dernier.

    Je préfère avoir des widgets de type différents dont les types souches sont génériques, c'est à dire Q< T, U, V, W > plutôt que QTUVW, QTUWV, QUTVW, QTUVW, pour ensuite m'amuser à upcaster tout le bordel et essayer de s'y retrouver...

    Quant à l'héritage par interface unique, oui, mais tu dois alors souvent trop charger tes interfaces, ce qui est un autre problème en soi.

  10. #30
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Ah oui j'avais zappé les questions désolé

    Sinon, pour appuyer ce que dis Julien, je rajouterais que si tu as une classe Widget paramétrée par 4 politiques. Si la première a 3 implémentations, la deuxième 4, la troisième 2, et la quatrième 5, ça te fait 3*4*2*5 classes à implémenter si tu veux faire l'équivalent qu'avec l'héritage. C'est à dire 120 classes. Plutôt que justement 3+4+2+5 = 14 classes, qui ne seront que des petits bouts de classe en fait !

    Entre 120 et 14, le choix pour moi est vite fait, et le sera probablement également pour un chef de projet correct

Discussions similaires

  1. Type erasure et accesseurs
    Par coda_blank dans le forum Langage
    Réponses: 27
    Dernier message: 28/08/2010, 23h46
  2. associer un type de contenu a une liste par programmation
    Par samworkflow dans le forum SharePoint
    Réponses: 6
    Dernier message: 11/05/2009, 11h18
  3. [POO] PHP et Programmation objet
    Par debianben dans le forum Langage
    Réponses: 5
    Dernier message: 13/02/2006, 12h43
  4. [POO] apprendre la programmation orientée objet
    Par Invité dans le forum Langage
    Réponses: 5
    Dernier message: 10/12/2005, 12h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo