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

C++ Discussion :

Dynamic_cast & Base class virtuelle


Sujet :

C++

  1. #1
    Membre à l'essai
    Inscrit en
    Avril 2005
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 42
    Points : 18
    Points
    18
    Par défaut Dynamic_cast & Base class virtuelle
    Bonjour,
    En lisant la documentation MSDN a propos du dynamic_cast, je me suis arrêté sur les quelques lignes traitant des classes bases virtuelles. Il y est dit que pour caster de A vers B (voir http://msdn.microsoft.com/library/de...t_operator.asp), on doit auparavant caster de A à E, et ensuite remonter (upcast) jusqu'a E. J'ai essaye, et ca ne fonctionne pas, voici mon code de test...

    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
     
    #include <iostream>
     
    using namespace std;
     
     
    class A { public: virtual ~A() { } };
     
    class B : virtual public A { };
     
    class C : virtual public B { };
     
    class D : virtual public B { };
     
    class E : virtual public C, virtual public D { };
     
     
    int main()
    {
    	E e;
     
    	A *pA = &e;
    	E *pE = dynamic_cast<E *>(pA);
     
     
    	return 0;
    }
    Vous savez d'ou cela peut prevenir ?
    Merci

  2. #2
    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 519
    Points
    41 519
    Par défaut
    Je viens de tester sous Dev-C++, ça marche parfaitement!

    Le code fait l'upcast implicite de &E en A*, puis le downcast dynamique de A* vers E*, sans problème...

    Qu'est-ce qui ne marche pas chez toi?
    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. #3
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    a- Toutes tes classes sont partagées -- ce qui ne correspond pas aux hiérarchies montrées dans la doc citée et donc aux problèmes d'ambiguités à lever. Tu as codé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
      A
      |
      B
     / \
    C   D
     \ /
      E
    Redocumente-toi sur l'héritage virtuel et son implication dans l'héritage multiple.
    p.ex. en faisant sauter les héritages virtuels de C et D vers B, tu aurais eu deux B englobant tous deux le même A. Là, il y aurait pu y avoir des problèmes d'ambiguité à gérer. Dans E, de quel B parle-t-on ? de celui intégré à C ? ou bien de celui intégré à D? Donc => passer par C ou D pour remonter à leur B non partagé.

    b- Je ne vois pas le rapport entre ta question et ce que tu as écris dans ton main(). Ton code ne correspond pas à ce dont tu parles au dessus.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  4. #4
    Membre à l'essai
    Inscrit en
    Avril 2005
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 42
    Points : 18
    Points
    18
    Par défaut
    a- Toutes tes classes sont partagées -- ce qui ne correspond pas aux hiérarchies montrées dans la doc citée et donc aux problèmes d'ambiguités à lever.
    Ha ok, je pense avoir compris...
    Dans mon code, j'ai utilisé uniquement des classes partagées, c'est donc vrai qu'il n'y a pas de problèmes d'ambiguïté comme dans mon indiqué dans le lien de la msdn... dsl

    Par contre, des problèmes d'ambiguïté peuvent intervenir dans ce code :

    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
     
    #include <iostream>
     
    using namespace std;
     
    class A
    {
    };
     
    class B : public A
    {
    };
     
    class C : public A
    {
    };
     
    class D : public B, public C
    {
    };
     
     
    int main()
    {
       D *d = new D;
     
    // A *a = d;   // upcast  --> Ambigous
     
       C *c = d;   // on upcast par C
       A *a = c;   // .. et finalement upcast vers A  --> pas ambigous
     
       return 0;
    }
    Médinoc >> Merci pour ton essai, chez moi ça compile mais le programme plante...

    Luc >> Comment tu illustrerais le schéma de Class Hierarchy Showing Virtual Base Classes alors ?

    Merci pour vos réponses.

  5. #5
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Citation Envoyé par taron
    Luc >> Comment tu illustrerais le schéma de Class Hierarchy Showing Virtual Base Classes alors ? pas comme je l'ai fait ?
    Exactement comme je te l'avais dit. Je peux me tromper, mais je vois ça ainsi:
    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
    90
    91
    92
    93
    94
    95
    96
    97
    // illustration de "Class Hierarchy Showing Virtual Base Classes"
    //
    //    A
    //   / \
    //  B   B
    //  |   |
    //  C   D
    //   \ /
    //    E
    //
     
    #include <iostream>
    #include <cassert>
     
    struct A {
        A(int a) : a_(a) {}
     
        // ctr par défaut avec assertion pour forcer à appeler A(int) 
        // depuis les classes finales
        A() { assert(false && "Wrong compilation path"); }
     
        virtual ~A() {}
        void print_a() const { std::cout << "a="<<a_ << std::endl;}
    private:
        int a_;
    };
     
    struct B : virtual A {
        B(int b) : b_(b) {}
        virtual ~B() {}
        void print_b() const { std::cout << "b="<<b_ << std::endl;}
    private:
        int b_;
    };
     
    struct C : B {
        C(int bc, int c) : B(bc), c_(c) {}
        virtual ~C() {}
        void print_c() const { std::cout << "c="<<c_ << std::endl;}
    private:
        int c_;
    };
     
    struct D : B {
        D(int bd, int d) : B(bd), d_(d) {}
        virtual ~D() {}
        void print_d() const { std::cout << "d="<<d_ << std::endl;}
    private:
        int d_;
    };
     
    struct E : C, D {
        E(int a, int bc, int bd, int c, int d, int e) 
    	: A(a), C(bc, c), D(bd, d), e_(e) {}
        virtual ~E() {}
        void print_e() const { std::cout << "e="<<e_ << std::endl;}
    private:
        int e_;
    };
     
     
    int main()
    {
        E e(1,2,3,4,5,6);
     
        std::cout << "Depuis E:\n";
        e.print_e();
        e.print_d();
        e.print_c();
        // e.print_b(); // ambigüe
        e.print_a();
     
        std::cout << "Depuis D:\n";
        D * d = &e;
        d -> print_d();
        // d -> print_c(); // evidemment pas accessible
        d -> print_b();
        d -> print_a();
     
        std::cout << "Depuis C:\n";
        C * c = &e;
        // c -> print_d(); // evidemment pas accessible
        c -> print_c();
        c -> print_b();
        c -> print_a();
     
        // B * b = &e; // ambigüe
        std::cout << "Depuis B via C:\n";
        B * bc = c;
        bc -> print_b();
        bc -> print_a();
     
        std::cout << "Depuis B via D:\n";
        B * bd = d;
        bd -> print_b();
        bd -> print_a();
    }
    Si je me souviens bien, dans les articles aggrégés sur le developer-pipeline (lien accessible depuis le site de http://www.cuj.com), il y avait un article tentant de démystifier l'héritage multiple.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  6. #6
    Membre à l'essai
    Inscrit en
    Avril 2005
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 42
    Points : 18
    Points
    18
    Par défaut
    Yeah, merci beaucoup :-)

Discussions similaires

  1. Réponses: 8
    Dernier message: 16/10/2006, 12h28
  2. Classe virtuelle detructeur virtuel
    Par Jeane dans le forum C++
    Réponses: 3
    Dernier message: 26/06/2006, 23h06
  3. Réponses: 2
    Dernier message: 01/02/2006, 15h02
  4. directshow bases classes
    Par moldavi dans le forum DirectX
    Réponses: 3
    Dernier message: 30/03/2005, 21h59

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