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 :

Souci de la forme: A *a = new B;


Sujet :

C++

  1. #1
    Membre du Club
    Inscrit en
    Décembre 2005
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 112
    Points : 54
    Points
    54
    Par défaut Souci de la forme: A *a = new B;
    Voilà j'ai un petit problème avec les ligatures dynamiques:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    MaBase* pBase[4][5]; //déclaration du tableau
     
    pBase[0][0] = new MaBase(); //occurence de la classe de base
     
    pBase[0][1] = new MaDerivee();//occurence de la classe dérivée
    Jusque là tout semble marcher mais en fait non car pBase[0][1] ne possède pas les attributs de MaDerivee.

    De plus j'ai fait un test du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    MaDerivee *test = new MaDerivee();//occurence de la classe dérivée
    et test possède l'attribut de MaDerivee et seulement quelques uns de la classe de base.

    Le problème doit être dans les constructeurs, je pense. Ils sont très simples pourtant.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    MaBase::MaBase()
    {
    	attribut1 = 0; //posséder par l'occurence test
    	attribut2 = 0;// pas posséder
    	attribut3 = "";//posséder
    	attribut4 = "";//pas posséder
    	for(int i = 0; i < 2; i++)
    		attribut5[i] = "";//posséder
    }
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    MaDerivee::MaDerivee():MaBase()
    {
     
    }
    sachant que MaDerivee et MaBase possède aussi des attributs de type: classe développée par moi.

    problème: pBase[0][1] ne possede pas les arguments de la dérivée et les occurences de la dérivée n'ont pas accès à tous les attributs de la base

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    731
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 731
    Points : 574
    Points
    574
    Par défaut
    Ca a l'air normal, tu déclares un tableau statique contenant exactement la taille de ta classe de base. Donc pBase[0][1] ne contient pas les éléments de la classe dérivée.
    Je pense que c'est ça, je ne travaille jamais avec des tableaux statiques.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    les occurences de la dérivée n'ont pas accès à tous les attributs de la base
    Il faut déclarer les membres de ta classe de base protected et faire un héritage public dans ta classe dérivée.

  3. #3
    Membre du Club
    Inscrit en
    Décembre 2005
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 112
    Points : 54
    Points
    54
    Par défaut
    Citation Envoyé par ep31
    Ca a l'air normal, tu déclares un tableau statique contenant exactement la taille de ta classe de base. Donc pBase[0][1] ne contient pas les éléments de la classe dérivée.
    Je pense que c'est ça, je ne travaille jamais avec des tableaux statiques.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    les occurences de la dérivée n'ont pas accès à tous les attributs de la base
    Il faut déclarer les membres de ta classe de base protected et faire un héritage public dans ta classe dérivée.
    pBase[0][1] est un pointeur.
    Normalement si je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaBase pBase[0][1] = new MaDerivee();
    Je lui affecte la taille mémoire de la classe dérivée, non?

    Sinon je vais aller essayer pour les attributs en protected. Ca ne résoudra pas mon problème mais on ne perd jamais rien à apprendre

    Merci.

  4. #4
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    pBase[0][1] ne possede pas les arguments de la dérivée
    C'est un Base*, donc normal que tu ne puisses plus accéder aux données de Derivee (en dehors de liens dynamiques -- fonctions virtuelles).

    les occurences de la dérivée n'ont pas accès à tous les attributs de la base
    Faudrait préciser ce qui se passe. Erreur de compilation ? Si oui laquelle ?

    De plus tu étais sur le mauvais forum, ce problème n'est pas lié à Visual C++.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    731
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 731
    Points : 574
    Points
    574
    Par défaut
    Je lui affecte la taille mémoire de la classe dérivée, non?
    Oui en effet, j'avais zappé le pointeur.
    Pour accéder aux valeurs de ta classe dérivée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    MaDerivee *pTest;
    pTest = static_cast<pTest*>(pBase[0][1]);
    Tu pourras ensuite accéder aux membres de ta classe dérivée brâce à pTest

  6. #6
    Membre du Club
    Inscrit en
    Décembre 2005
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 112
    Points : 54
    Points
    54
    Par défaut
    Ok! Pardon. En fait j'étais tellement sur de moi que je pensais que c'était dû à une particularité de Visual C++ mais il semblerait plutôt qu je n'ai rien compris aux ligatures dynamiques.

    Première question toute bête: ligature et lien dynamique, est ce la même chose?

    sinon pour le fond du problème:
    je pensais que quand on faisait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaBase *pBase = new MaDerivee();
    On faisait un lien dynamique et ainsi on avait accès aux données de la base et de la dérivée.
    si oui,le fait que je fasse
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaBase *pBase[0][1] = new MaDerivee();
    change t il quelque chose?

    Pour la deuxième partie. oui ça fait une erreur à la compilation mais en fait elle était là juste pour donner des pistes.

    Merci.

  7. #7
    Membre du Club
    Inscrit en
    Décembre 2005
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 112
    Points : 54
    Points
    54
    Par défaut
    oups posté en retard!! pardon

    Encore ce static_cast. 2 fois que je bloque sur lui.

    Il fit partie du C++ ou de visual?

    Je fais me faire un petit coup de google ou de FAQ pour voir ça.

    Merci je vais tester ta solution

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    731
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 731
    Points : 574
    Points
    574
    Par défaut
    Le static_cast fait partie de C++ (pas spécifique Visual), il remplace les cast C.
    Il permet de caster un objet dont tu es sur de son type (contrairement au dynamic_cast).

  9. #9
    Membre du Club
    Inscrit en
    Décembre 2005
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 112
    Points : 54
    Points
    54
    Par défaut
    Bon en fait j'ai fait une erreur honteuse pour ce qui est de dire que "les occurences de la dérivée n'ont pas accès à tous les attributs de la base"
    . Je me suis fié à l'affichage de Visual sans tester et en fait j'aurai dû.
    Je suis tout confus . désolé

    En revanche, je n'arrive toujours pas à faire la ligature dynamique:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    MaBase *pBase[0][1] = new MaDerivee();
    Merci ep31 de ta réponse mais en fait c'est dans l'autre sens que j'en ai besoin.
    et merci pour le static_cast, je l'oublierai pas celui-là!

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    731
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 731
    Points : 574
    Points
    574
    Par défaut
    En revanche, je n'arrive toujours pas à faire la ligature dynamique
    Quel est exactement le problème ?
    Pas un problème de compil non ? Ca a l'air correct.

  11. #11
    Membre du Club
    Inscrit en
    Décembre 2005
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 112
    Points : 54
    Points
    54
    Par défaut
    Je te mets tout le code.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    CMaBase* pBase[4][5];
     
    pBase[0][0] = new CMaBase();
    pBase[0][1] = new CMaBase();
    // attribution de valeurs aux attributs de la clase de base
     
    pBase[0][2] = new CMaDerivee();
    // attribution de valeurs aux attributs de la clase de base
    pBase[0][2]->m_AttributDerivee = valeur;
    Erreur de compilation: m_AttributDerivee is not a member of 'CBase'

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    731
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 731
    Points : 574
    Points
    574
    Par défaut
    Il faut mettre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    static_cast<CMaDerivee*>(pBase[0][2])]->m_AttributDerivee = valeur;
    ou plus propre et plus lisible :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    CMaDerivee * ptUtil;
    ptUtil = static_cast<CMaDerivee*>(pBase[0][2]);
    ptUtil->m_AttributDerivee = valeur;
    Je pense que ça marchera.

  13. #13
    Membre du Club
    Inscrit en
    Décembre 2005
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 112
    Points : 54
    Points
    54
    Par défaut
    Citation Envoyé par ep31
    Il faut mettre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    static_cast<CMaDerivee*>(pBase[0][2])]->m_AttributDerivee = valeur;
    ou plus propre et plus lisible :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    CMaDerivee * ptUtil;
    ptUtil = static_cast<CMaDerivee*>(pBase[0][2]);
    ptUtil->m_AttributDerivee = valeur;
    Je pense que ça marchera.
    La première marche mais c'est chaint si je dois écrire ça à chaque fois non?

    La deuxième marche. je l'ai essayé quand tu l'as dit tout à l'heure mais après il faut que je fasse

    static_cast<CMaDerivee*>(pBase[0][2]) = ptUtil ?

    En tout cas je te remercie. je suis débloqué même si je comprends toujours pas pourquoi ça marche sans le cast.
    Tu m'as sauvé la vie

  14. #14
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Il faut passer par le downcasting (voir FAQ).

    Mais en général lorsqu'on manipule un pointeur sur classe de base c'est qu'on n'a pas besoin d'accéder aux données des classes dérivées (voir FAQ aussi).

  15. #15
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    731
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 731
    Points : 574
    Points
    574
    Par défaut
    La deuxième marche. je l'ai essayé quand tu l'as dit tout à l'heure mais après il faut que je fasse

    static_cast<CMaDerivee*>(pBase[0][2]) = ptUtil ?
    Non pas besoin vu que tu utilises un pointeur.

  16. #16
    Membre du Club
    Inscrit en
    Décembre 2005
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 112
    Points : 54
    Points
    54
    Par défaut
    OK merci!!

    finalement j'ai utilisé la deuxième technique et ça marche!!

    Résolution 2006: se plonger dans le casting

    A bientot

  17. #17
    Membre averti
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Points : 353
    Points
    353
    Par défaut
    Se plonger dans les cast ..... ou revoir la conception
    Citation Envoyé par Loulou24
    Il faut passer par le downcasting (voir FAQ).
    Mais en général lorsqu'on manipule un pointeur sur classe de base c'est qu'on n'a pas besoin d'accéder aux données des classes dérivées (voir FAQ aussi).
    (cf. les liens à la fin du post)


    Et sinon, Attention code dangereux !
    (d'ailleurs j'imagine que le compilateur t'a fait un warning non ?)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    CMaDerivee * ptUtil;
    ptUtil = static_cast<CMaDerivee*>(pBase[0][2]);
    ptUtil->m_AttributDerivee = valeur;
    Voilà un post trouvé sur un forum anglais qui résume bien tout cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    CParent *pParent = new CParent;
    pChild = static_cast<CChild *> (pParent);
    pChild->print();
    This is a BAD idea - you are right in Undefined-Behaviour-Land. Casts are unnecessary when you want to convert from child to parent, but they are very much needed when you convert from parent to child.

    static_cast doesn't, cannot verify that the parent pointer you gave it really points to a child or not. All it can check is that the parent and child classes are related. It doesn't check the object - that's the job of dynamic_cast.

    Here you're "lucky" because your print function doesn't actually rely on any of the child class properties that aren't already present in parent.
    But what if print were to call virtual member functions of child that do not exist in parent? The compiler would blindly go access inexistant vtbl entries, happily sending your program on a one-way trip to Segfault-Land. And that's if you're lucky.

    If you're unlucky, the member function will write to some child member variable that doesn't exist in parent, therefore writing outside the object, either in memory you do not own, causing your application to Segfault (again, if you're lucky), or will overwrite another object's data (if you aren't). If your object is on the stack, you may even end up wiping out your stack frame, which is never a good thing. If the data you're writing comes from user input, you're offering crackers a gigantic security hole on a silver platter for them to exploit.
    La solution serait donc dynamic_cast :il va renvoyer NULL si pBase[0][2] n'est pas vraiment un CMaDerivee (rien ne t'en assure).
    Mais bon comme l'a dit Loulou24 le downcasting est à éviter, je ne pense pas qu'il soit nécessaire ici ! C'est le début de la spirale infernale du code non-maintenable

    Regarde ce document qui explique en quoi le downcasting n'est pas conseillé et enlève l'aspect objet du code : http://www.artima.com/interfacedesign/PreferPoly.html

    et le lien vers la FAQ http://c.developpez.com/faq/cpp/?pag...RS_downcasting
    And still we will be here, standing like statues ...

  18. #18
    Membre du Club
    Inscrit en
    Décembre 2005
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 112
    Points : 54
    Points
    54
    Par défaut
    Bon alors ok Mais je vais prendre un exemple une peu concret histoire de voir comment vous le feriez parce que je vous avoue je suis un peu perdu là.

    J'ai un tableau de personnes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CPersonne *pPers[50];
    Avec comme attribut nom, prénom.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    *pPers[0] = new CPersonne;
     
    *pPers[0]->m_sPrenom =" Laurent";
    *pPers[0]->m_sNom ="Dupont";
    Mais certaines de ces personnes sont des élèves et possèdes l'attribut note.
    donc classe CEleve dérivée de CPersonne.
    Et je suis obligé de réutiliser le tableau pour faire des statistiques ou je ne sais quoi
    donc je voudrais que dans ce tableau il y ai des élèves et des personnes normales mais je veux aussi affecter une note à ces élèves. donc je voudrai faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    *pPers[1] = new CEleve;
     
    *pPers[1]->m_sPrenom = "Harry";
    *pPers[1]->m_sNom = "Potter";
     
    //et
     
    *pPers[1]->m_iNote = 12;// et c'est là que ça bloque!! m_iNote pas membre de CPersonne
    J'ai lu la FAQ pas encore ton site et je sais pourquoi faut pas le faire maintenant mais pas comment le faire sans utiliser le dynamic_casting qui semble pas bien si je comprends bien!!

  19. #19
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    S'il ne s'agit que d'ajouter des informations à la construction de l'objet, alors passe ta note au constructeur de CEleve.

    Si par contre il s'agit aussi d'effectuer des traitements spécifiques aux élèves, alors le mieux est certainement de conserver un tableau ne contenant que les élèves, parallèlement au tableau de personnes. Ca nécessite des traitements supplémentaires mais c'est déjà plus propre.

  20. #20
    Membre du Club
    Inscrit en
    Décembre 2005
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 112
    Points : 54
    Points
    54
    Par défaut
    Moi qui croyais que justement cétait propre de développer comme ça, je me suis bien roulé tout seul.

    Et quand j'y repense c'est vrai que c'est plus clair si dans le code on sait rien qu'en la voyant qu'elle est le type d'une variable mais je trouvais ça classe.

    Le problème est le même si je passe par le constructeur, non? Je ne pourrai pas récupérer la valeur note bien qu'elle soit initialisée?

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [XL-2007] soucis dans USER FORM
    Par alf049 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 15/06/2012, 14h15
  2. [2.x] Form différent en new et edit
    Par jfsenechal dans le forum Symfony
    Réponses: 4
    Dernier message: 22/11/2011, 12h22
  3. Souci dans la forme !
    Par Erolgamer dans le forum Merise
    Réponses: 2
    Dernier message: 13/03/2010, 09h26
  4. [HTML 4.0] souci avec imbrication form et table
    Par rapanui dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 08/06/2009, 20h04
  5. [Forms 10g] When-New-Form-Instance Niveau Bloc
    Par star dans le forum Forms
    Réponses: 6
    Dernier message: 25/03/2006, 21h22

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