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++Builder Discussion :

[C++]closure + héritage + transtypage


Sujet :

C++Builder

  1. #1
    JEG
    JEG est déconnecté
    Membre éclairé
    Avatar de JEG
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 211
    Points : 727
    Points
    727
    Par défaut [C++]closure + héritage + transtypage
    Bonjour,

    J'ai une classe B héritant d'une classe A de la VCL :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class B : public A
    {
             public:
             void __closure * methodeB1();
             void methodeB2();
    };
    methodeB2 contenant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ShowMessage("avantB1");
    methodeB1();
    ShowMessage("apresB1");
    (ne tenez pas compte des erreurs de syntaxe, j'écris en simplifiant)

    maintenant imaginons que A soit par exemple un TreeView, qui a été instancié dans une forme l'outil de création de forme.
    (On appelera "a" l'instance de A)

    dans mon code j'ai qqc de la sorte:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    B * b = (B *)a;
    b->methodeB1 = maMethode;
    b->methodeB2();
    et à l'exécution il se trouve que la méthode B2 est belle et bien appelée, que tout s'y déroule bien si ce n'est lors de l'appel à methodeB1 qui déclenche une erreur de type "erreur à l'adresse bidulle" et donc ne rentre jamais dans le corps de maMethode.

    D'où ma question :
    un closure est-il traité comme une variable de classe (ce qui expliquerait que b doive obligatoirement être une instance de B) ou bien comme une vraie méthode (dans ce cas b peut etre un transtypage d'une instance de A, et je ne vois pas pourquoi ca ne marche pas)

    D'avance merci

  2. #2
    ubu
    ubu est déconnecté
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2002
    Messages : 38
    Points : 47
    Points
    47
    Par défaut
    Salut, un __closure est effectivement traité comme un attribut (variable de classe?!?) dans ton cas.
    Il s'agit d'un pointeur 64 bits (@methode: 32 bits et @classe: 32 bits).

  3. #3
    JEG
    JEG est déconnecté
    Membre éclairé
    Avatar de JEG
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 211
    Points : 727
    Points
    727
    Par défaut
    Ok ca confirme ce que je pensais, merci !

  4. #4
    ubu
    ubu est déconnecté
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2002
    Messages : 38
    Points : 47
    Points
    47
    Par défaut
    J'aurais par contre une question qui me turlupine depuis que j'ai vu ce bout de code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    B * b = (B *)a; 
    b->methodeB1 = maMethode; 
    b->methodeB2();
    Le pointeur a considéré ici est il de type A (Treeview ou autre) ?

  5. #5
    JEG
    JEG est déconnecté
    Membre éclairé
    Avatar de JEG
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 211
    Points : 727
    Points
    727
    Par défaut
    Affirmatif (j'ai corrigé mon texte)

  6. #6
    ubu
    ubu est déconnecté
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2002
    Messages : 38
    Points : 47
    Points
    47
    Par défaut
    OK, c'est bien ce que je pensais. J'aurai une question alors:

    Est ce que Borland à prévu officiellement dans l'implémentation de son compilo qu'un downcasting brutal de ce type soit géré ?
    Car logiquement, on devrait faire un safe-downcasting en utilisant un dynamic_cast, non ?
    Quel est l'intérêt de ce downcasting brutal, et surtout, qu'est ce qui se passe à l'éxecution ?
    Normalement, les attributs et les méthodes déclarés dans B et non hérités de A devraient poser un gros problème, non ?

  7. #7
    JEG
    JEG est déconnecté
    Membre éclairé
    Avatar de JEG
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 211
    Points : 727
    Points
    727
    Par défaut
    Citation Envoyé par ubu
    OK, c'est bien ce que je pensais. J'aurai une question alors:

    Est ce que Borland à prévu officiellement dans l'implémentation de son compilo qu'un downcasting brutal de ce type soit géré ?
    Car logiquement, on devrait faire un safe-downcasting en utilisant un dynamic_cast, non ?
    Quel est l'intérêt de ce downcasting brutal, et surtout, qu'est ce qui se passe à l'éxecution ?
    Normalement, les attributs et les méthodes déclarés dans B et non hérités de A devraient poser un gros problème, non ?
    l'intérêt de ce transtypage réside dans le fait d'enrichir les foncitonanlités du TreeView tout en conservant la création du composant par l'éditeur de fiche. Tout marche bien à partir du moment il la classe B ne comporte aucun attribut dont on se serve, si il n'y a que des méthodes par exemple ca marche très bien étant donnée que les méthodes sont gérées de façon statiques donc qu'elles existent à partir du moment là classe est déclarée (a contrario des attributs qui n'existe que dans le cas d'une instanciation)
    donc si l'on n'enrichit la classe qu'avec des méthodes cette sorte de transtypage est géré par (je crois) la totalité des compilateurs C++.

    Bien sur n'est pas très une méthode très "Object Oriented" au sens puriste du terme, mais ca me permet une certaine souplesse dans mes développement.

    dynamic_cast, je ne connais pas bien. Quel est la différence avec le cast normal ?

  8. #8
    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 JEG
    dynamic_cast, je ne connais pas bien. Quel est la différence avec le cast normal ?
    GOTW #17
    Le cast normal n'est pas adapté au C++. C'est plus un reliquat de compatibilité avec le C qu'autre chose.
    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...

  9. #9
    ubu
    ubu est déconnecté
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2002
    Messages : 38
    Points : 47
    Points
    47
    Par défaut
    cette sorte de transtypage est géré par (je crois) la totalité des compilateurs C++.
    Je ne suis pas sur du tout de cela. En tout cas, il n'existe pas de norme pour ce transtypage. Le résultat n'est donc jamais assuré. Cependant, il est tout a fait possible que, rien n'étant spécifié, Borland ai pris le parti de le supporter (d'ou ma question précédente).

    Le dynamic_cast permet d'effectuer ce type de transtypage en se basant sur le RTTI, et donc d'une manière très sure (typesafe). Par ex:

    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
    class A {};
    class B: public A {};
     
    A* a1,a2;
    B* b1,b2;
     
    a1=new A();
    b1=new B();
     
    a2=b; // <= aucun problème, upcast implicite
     
    b2=dynamic_cast<B*>(a2); // équivalent à b2=(B*)a2; mais avec vérification du type. On peut alors tester le résultat
     
    if (b2!=NULL)
      ... // si b2 existe, alors ce downcasting était autorisé (ce A était un B)
    else
      ... // sinon, ce A n'était pas un B
     
    b2=dynamic_cast<B*>(a1); // b2 vaudra NULL, puisqu'il s'agit d'un A

  10. #10
    JEG
    JEG est déconnecté
    Membre éclairé
    Avatar de JEG
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 211
    Points : 727
    Points
    727
    Par défaut
    Citation Envoyé par ubu
    En tout cas, il n'existe pas de norme pour ce transtypage.
    Vu qu'il s'agit juste d'une conversion de pointeur, ca reviendrait à dire que le cast utilisant les parenthèse "()" n'est pas normalisé, et ca me parait étrange à vrai dire...

  11. #11
    ubu
    ubu est déconnecté
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2002
    Messages : 38
    Points : 47
    Points
    47
    Par défaut
    Je voulais dire que le résultat effectif (comportement de l'instance pointée)de ce trantypage n'est pas normalisé. Par contre effectivement, le pointeur sur A est bel et bien typé en B, mais sans contrôle de type. En gros c'est comme faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int i;
    B *b;
    b=(B*)i;
    Ca doit fonctionner, mais alors à l'execution, ben heu...

  12. #12
    JEG
    JEG est déconnecté
    Membre éclairé
    Avatar de JEG
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 211
    Points : 727
    Points
    727
    Par défaut
    A mon avis, je pense que tout compilo C++ qui gère le concept d'interface basée sur classes abstraites doit pouvoir gérer ce que j'ai fait. Si l'on part du principe que tous les compilo C++ gèrent le système d'interface, ca me laissait penser que ce que j'ai fait marchait sur tous les compilo. A tester donc...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [PHP 5.0] Héritage et transtypage PDOStatement
    Par im-souf dans le forum Langage
    Réponses: 2
    Dernier message: 02/12/2011, 13h37
  2. Problème d'héritage et de transtypage
    Par Higgins dans le forum C#
    Réponses: 12
    Dernier message: 07/01/2011, 18h08
  3. transtypage, héritage et surcharge!
    Par Syphys dans le forum Langage
    Réponses: 3
    Dernier message: 16/11/2009, 14h44
  4. héritage / transtypage
    Par Michel_57 dans le forum C++
    Réponses: 28
    Dernier message: 05/10/2007, 13h33
  5. Héritage entre Forms
    Par BarBal dans le forum Composants VCL
    Réponses: 7
    Dernier message: 29/08/2002, 17h44

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