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 :

Choix entre 2 typedef de taille différente, à l'exécution


Sujet :

C++

  1. #1
    Membre du Club
    Inscrit en
    Février 2010
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 9
    Par défaut Choix entre 2 typedef de taille différente, à l'exécution
    Merci de m'accueillir parmi vous. Je débute et j'aimerai svp avoir de l'aide.
    Voici mon problème:
    Je dispose de 2 structures différentes, et j'aimerai que le programme
    utilise une ou l'autre définition, selon le paramètre passé en ligne de commande.
    Pour des raisons propre au programme, j'aimerai conserver le même nom d'identificateur pour les 2 structures.

    Je m'explique:

    Dans unit1.cpp, form principale, j'ai mis:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void __fastcall TForm1::FormCreate(TObject *Sender) {
     
    ....
    	MODEL_REC = N_MODEL_A;
    	if (LowerCase(ParamStr(1)) == "-modeleb") 
    		MODEL_REC = N_MODEL_B;
    ....
     
    }
    On voit que, par défaut (sans aucune ligne de commande), MODEL_REC = N_MODEL_A.
    Si par contre, on exécute: MonProg.exe -modeleb, alors MODEL_REC prend la valeur N_MODEL_B.


    Dans unit1.h, je dispose de:
    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
     
    #ifndef Unit1H
    #define Unit1H
     
      #define N_MODEL_A    0
      #define N_MODEL_B    1 
     
    // etc....
     
    typedef struct {
    	int  Port;
    	char User[30];
    	char Pass[20];
    }S_MODEL;
     
     
    /* Le choix doit porter sur les 2 structures ci dessous */
    /*=========================================*/
     
     
     /* définition de la structure MODEL_S par défaut. MODEL_REC = N_MODEL_A */
     
       typedef struct {
    	char name[20];
    	int  numero;
    	S_MODEL Model_Actif;
        }MODEL_S;
     
     
    /* définition de la structure MODEL_S  si paramstr(1) = "-modeleb*/
     
       typedef struct {
    	char name[40];
    	int  numero;
            char MyKey[14];  
    	S_MODEL Model_Actif;
      }MODEL_S;
     
    private:	// User declarations
     
    public:	// User declarations
    		 int MODEL_REC;
    		__fastcall TForm1(TComponent* Owner);
     
    };
     
    extern PACKAGE TForm1 *Form1;
     
    #endif
    Comment je dois disposer les définitions, en tenant compte que je suis obligé de garder le même nom d'identificateur, en l'occurence, MODEL_S
    Merci beaucoup pour votre aide. Y a t'il une autre astuce ? Merci encore.

  2. #2
    Membre du Club
    Inscrit en
    Février 2010
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 9
    Par défaut
    J'ajoute que l'élément MyKey[14] n'est pas utilisé du tout dans le programme.
    Seuls les éléments de même nom sont utilisés. (name, numero et Model_Actif) .

    J'aimerai avoir à manipuler qu'une seule variable (MyData) que je déclare dans une autre fiche (unit2.cpp) (les relations entre unités étant faites bien sûr)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    static MODEL_S MyData
    Finalement, ma question pourrait être: Comment redéfinir un typedef à l'exécution ?

    Je ne sais pas si je me fais comprendre

  3. #3
    Membre Expert
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Par défaut
    je ne suis pas sur de bien comprendre le problème, mais quoi qu'il en soit, ce que tu veux faire ne pourra se faire qu'a la compilation et jamais pendant l'exécution.

    Je pense que le meilleurs moyen pour obtenir ton résultat est soit d'utiliser des préprocesseurs (#if MODEL_REC ==N_MODEL_B) ou bien de faire en sorte que model_S soit template.

    Par contre, j'avoue ne pas comprendre comment fonctionne ta fonction void __fastcall TForm1::FormCreate(TObject *Sender) , mais bon, je ne connais pas grand chose à ces histoire de paramètres de compilation...

    Bonne chance.

  4. #4
    Membre du Club
    Inscrit en
    Février 2010
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 9
    Par défaut
    Un gros gros MERCI, Méphistophélès.
    J'ai oublié de dire que je suis sous RAD Studio C++ 2010.
    J'ai essayé les preprocessurs #ifdef , le compilateur prend toujours la valeur 0 pour MODEL_REC, même si j'initialise cette valeur à 1 dans unit1.cpp

    que ce soit çà:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #if MODEL_REC ==N_MODEL_A
    ...
    #elseif MODEL_REC ==N_MODEL_B
    ...
    #endif
    ou çà
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #if MODEL_REC ==N_MODEL_B
    ...
    #elseif MODEL_REC ==N_MODEL_A
    ...
    #endif
    Pour les templates, je n'ai pas essayé mais il va falloir que je change tout le code quand je fais référence à ma variable MyData.

    Quant au morceau de code, il a été rajouté par l'EDI. C'est la définition de la Form que j'utilise. Je n'y suis pour rien.

    J'ai même déplacé le morceau de code dans la procédure
    TForm1::TForm1(TComponent* Owner) : TForm(Owner)
    avec le même résultat.


    En gros, voici une copie de l'unité unit1.h (j'ai supprimé des lignes, pour faire "petit")

    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
     
    class TForm1 : public TForm
    {
    __published:	// IDE-managed Components
    	TOpenDialog *OpenDialog1;
    	TPopupMenu *PopupMenu2;
     
    /*     etc..  déclare composants de la form  */
     
    	void __fastcall FormCreate(TObject *Sender); 
    	void __fastcall OpenClick(TObject *Sender);
    	void __fastcall BtnStartUpClick(TObject *Sender);
    /*    etc.... déclare proc et func de la form     */
     
    private:	// User declarations
     
    public:	// Public declarations
    		 int MODEL_REC;
    		__fastcall TForm1(TComponent* Owner);
     
    };
    Encore une fois, merci.

  5. #5
    Membre Expert
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Par défaut
    Citation Envoyé par ilovec Voir le message
    J'ai oublié de dire que je suis sous RAD Studio C++ 2010.
    Je conais pas désolé .
    Citation Envoyé par ilovec Voir le message
    J'ai essayé les preprocessurs #ifdef , le compilateur prend toujours la valeur 0 pour MODEL_REC, même si j'initialise cette valeur à 1 dans unit1.cpp
    comment l'initialise-tu ? on peut avoir un exemple ?


    Citation Envoyé par ilovec Voir le message
    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
     
    class TForm1 : public TForm
    {
    __published:	// IDE-managed Components
    	TOpenDialog *OpenDialog1;
    	TPopupMenu *PopupMenu2;
     
    /*     etc..  déclare composants de la form  */
     
    	void __fastcall FormCreate(TObject *Sender); 
    	void __fastcall OpenClick(TObject *Sender);
    	void __fastcall BtnStartUpClick(TObject *Sender);
    /*    etc.... déclare proc et func de la form     */
     
    private:	// User declarations
     
    public:	// Public declarations
    		 int MODEL_REC;
    		__fastcall TForm1(TComponent* Owner);
     
    };
    Jevoue que je ne vois pas comment TForm1::FormCreate pourrait changer model_rec de façon efficace : si model_rec est un préprocesseur, il n'existe plus apres compilation (et ne peut donc être modifié par une fonction) sinon, les préprocesseur ne pouvant comparer que des préprocesseur ou des fonctions...

    Par contre, une solution, serait d'écrire une macro qui remplace S_Model par une fonction qui choisisse d'instancier une classe ou une autre en fonction, par exemple, d'un paramètre (ou d'une variable globale, mais c'est très laid). Toutefois, cela exige que toutes tes instances de S_Model soit dynamique (et donc soit manipulées via des pointeurs ou des références .


    Bonne chance

  6. #6
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Euh je suis le seul à penser à un bon coup de polymorphisme dynamique avec une bonne encapsulation le couplé à une fabrique plutôt qu'à des hacks à coup de macros ?

    PS/ Je suppose que c'est réalisable car s'il veut pouvoir passer d'une méthode à une autre dynamiquement, c'est que les deux structures jouent le même rôle et donc qu'on peut factoriser une interface commune entre les deux.

    (pas le temps de plus détailler, sorry :S)
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  7. #7
    Membre Expert
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Par défaut
    Citation Envoyé par Davidbrcz Voir le message
    Euh je suis le seul à penser à un bon coup de polymorphisme dynamique avec une bonne encapsulation le couplé à une fabrique plutôt qu'à des hacks à coup de macros ?

    PS/ Je suppose que c'est réalisable car s'il veut pouvoir passer d'une méthode à une autre dynamiquement, c'est que les deux structures jouent le même rôle et donc qu'on peut factoriser une interface commune entre les deux.

    (pas le temps de plus détailler, sorry :S)
    j'y ai pensé, mais ça exige aussi de modifier un bon bout de code et je ne suis toujours pas sûr d'avoir compris ce qu'il veut faire :s

  8. #8
    Membre du Club
    Inscrit en
    Février 2010
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 9
    Par défaut
    Merci pour votre aide.

    1/ Je vais tenter d'être bref et clair à la fois.
    Supposons que j'ai 2 classes d'école, dont l'une possède 2 matières supplémentaires
    Soit la classe A: Français - Anglais - Maths
    la classe B: Français - Anglais - Maths - Histoire - Geo

    Pour la classe A, la structure sera:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     typedef struct 
    {
    	char name[20];	/* nom de l'élève */
            int   n_francais      /* note du français */
            int   n_anglais      
            int   n_maths      
    } notes_s;
    et pour la classe B:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     typedef struct 
    {
    	char name[30];	/* nom de l'élève  - Taille différente */
            int   n_francais    /* note du français */
            int   n_anglais      
            int   n_maths      
            int   n_histoire      
            int   n_geo      
    } notes_s;
    Les résultats sont inscrits donc sur un fichier qui ne possède pas un élément de structure indiquant sur quelle classe d'école on a affaire., si ce n'est la différence de taille qu'on peut calculer à l'aide de sizeof()

    Mon projet est donc le suivant (comprenez que pour moi, il s'agit simplement de LIRE le contenu d'un fichier qui possède déjà des données)

    Ma démarche a été la suivante. Je prends par défaut la structure notes_s correspondant à la classe d'école A.

    Après ouverture du fichier, je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    FileSeek(filehandle, 64, 0); 
     /* les 64 premiers octets sont réservés à d'autres éléments dont, malheureusement,*/
    /* aucun ne signifie le modèle de "classe d'école" dont on a affaire. */
     
    FileRead(filehandle, &MyData, sizeof(MyData)); /* filehandle étant le handle du fichie et */
    /* MyData est déclaré  comme: static notes_s MyData; */
    le tout, dans un bloc try - catch(...)

    Ensuite je fais appel à une fonction (trop longue à mettre ici) qui compare la taille de notes_s (sizeoff(MyData), avec la valeur retournée par la fonction.
    En cas d'égalité, on continue...
    En cas de non égalité, dans la bloc catch(...) .... et c'est là où je bloque...

    En dehors des méthodes classiques de fermeture du fichier etc... comment je pourrai "revenir en arrière" pour "désaffecter" la définition de la structure pour la classe d'école A et "reprendre" avec celle de la structure pour la classe d'école B, tout en gardant le même nom d'identificateur, en l'occurrence "notes_s"

    J'espère que je n'ai pas été long, sinon pardon

  9. #9
    Membre Expert
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Par défaut
    Heu... quelle est cette fonction FileRead ? ça me fais penser à la fonction read de ifstream, mais je préfère demander.

    En supposant que ce soit le cas, quelque-chose me turlupine: lorsque tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FileRead(filehandle, &MyData, sizeof(MyData));
    tu retire toujours le même nombre d'octets : le nombre d'octet du notes_s que tu utilisera pour l'occasion... je ne vois pas comment tu peux tester une égalité derrière... à moins que ton fichier ne contienne qu'un seul note_s auquel cas, il suffit de tester le flag pour savoir si on est à la fin du fichier avec la plus grande des deux structures, mais si ce n'est pas le cas, je ne comprend vraiment pas

  10. #10
    Membre du Club
    Inscrit en
    Février 2010
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 9
    Par défaut
    tu retire toujours le même nombre d'octets : le nombre d'octet du notes_s que tu utilisera pour l'occasion... je ne vois pas comment tu peux tester une égalité derrière... à moins que ton fichier ne contienne qu'un seul note_s auquel cas, il suffit de tester le flag pour savoir si on est à la fin du fichier avec la plus grande des deux structures
    Merci méphistopheles, de me répondre. C'est tout à fait ce que vous dites.

    Excusez mon insistance mais je m'exprime mal. Tout ce que je désire (c'est pour moi un exercice que je dois présenter), c'est grosso modo, sans entrer dans les détails, de m'indiquer la démarche la plus probable pour pouvoir "désallouer" (ou "désaffecter" si vous me comprenez) la première définition de structure et faire de la seconde structure, celle avec laquelle je pourrai continuer de travailler.
    Je me débrouillerai après pour savoir où les placer.

    PS: Je voudrai éviter de placer les structures dans une classe, ou utiliser des templates. Celà demanderai la transformation de pratiquement tout le code. Merci mille fois !

  11. #11
    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
    Par défaut
    Salut,
    Le type de ton objet :
    (1) si les types représentent visiblement deux cas concrets d'une même abstraction : classe de base + 2 classes dérivées et instanciation de la classe concrète adéquate à la lecture ;
    (2) sinon, si les types sont triviaux (ou compilateur C++0x) : une union ;
    (3) sinon, boost::variant<type1, type2>.

    La lecture : (puisque tu n'as aucune information directe à ce sujet dans ton fichier)
    (à la volée pour donner une idée) :
    (1)
    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
    struct ecole
    {
       virtual ~cours()=0;
    };
    struct ecole_1 : public cours
    {
       virtual~ecole_1(){}
    };
    struct ecole_2 : public cours
    {
       virtual~ecole_2(){}
    }
     
    std::auto_ptr<cours> lire(std::ifstream iff)
    {
       if(est_ecole_1(iff))
       {
           std::auto_ptr<cours> ret = new ecole_1;
           lire_ecole_1(ret);
           return ret;
       }
       else
       if(est_ecole_2(iff))
       {
           std::auto_ptr<cours> ret = new ecole_2;
           lire_ecole_2(ret);
           return ret;
       }
     
       throw ;
    }
    (2)
    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
     
    struct ecole_1
    {// trivial +- equiv à une structure C : 
    // sans constructeur,destructeur,operateur= 
    // -> versions implicites générées par le compilo
    // sans héritage ni fonctions virtuelles
    // et je crois mais je ne suis plus sûr (et flemme d'aller chercher) : tous les membres sont publics.
     
    };
    struct ecole_2
    {
    }
    union cours
    {
       ecole_1 e1;
       ecole_2 e2;
    }
     
    cours lire(std::ifstream iff)
    {
       if(est_ecole_1(iff))
       {
           cours ret;
           lire_ecole_1(ret.e1);
           return ret;
       }
       else
       if(est_ecole_2(iff))
       {
           cours ret;
           lire_ecole_2(ret.e2);
           return ret;
       }
       throw ;
    }
    (3)
    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
     
    struct ecole_1
    {
       ecole_1(int);
    };
    struct ecole_2
    {
       ecole_2(int);
    }
    typedef boost::variant<ecole_1,ecole_2> cours;
     
    cours lire(std::ifstream iff)
    {
       if(est_ecole_1(iff))
       {
           ecole_1 e1;
           lire_ecole_1(e1);
           return cours(e1);
       }
       else
       if(est_ecole_2(iff))
       {
           ecole_2 e2;
           lire_ecole_2(e2);
           return cours(e2);
       }
       throw ;
    }

  12. #12
    Membre Expert
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Par défaut
    Citation Envoyé par ilovec Voir le message
    Merci méphistopheles, de me répondre. C'est tout à fait ce que vous dites.
    heu... pourrais-tu développer ? tu veux dire qu'il n'y a qu'une classe stockée dans ton fichier ? et que tu teste le dépassement de fin de fichier ?

    Ce serait bien de dévelloper plus, ça réduirait le nombre de messages ...

  13. #13
    Membre du Club
    Inscrit en
    Février 2010
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 9
    Par défaut
    Merci 3DArchi. Je ne suis que de passage.
    Je vais essayer les 3 méthodes, histoire d'apprendre et d'approfondir mes connaissances. Je vous tiendrai au courant des résultats.

    En tous les cas, ce site est EXTRAORDINAIREMENT SERIEUX ET COMPETENT
    Quant à méphistopheles, je promets de vous répondre ce soir.
    A tous encore CHAPEAU BAS

  14. #14
    Membre Expert
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Par défaut
    Désolé de répondre un peu en retard à ton message 3D, j'avoue avoir eu la flemme de le lire hier ...

    Citation Envoyé par 3DArchi Voir le message
    (1)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct ecole
    {
       virtual ~cours()=0;
    };
    Je suppose que tu voulais écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct cours
    {
       virtual ~cours()=0;
    };
    Citation Envoyé par 3DArchi Voir le message
    (2)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    struct ecole_1
    {// trivial +- equiv à une structure C : 
    // sans constructeur,destructeur,operateur= 
    // -> versions implicites générées par le compilo
    // sans héritage ni fonctions virtuelles
    // et je crois mais je ne suis plus sûr (et flemme d'aller chercher) : tous les membres sont publics.
     
    };
    Je confirme... par contre, j'avais complètement oublié que ça existait encore les unions... faut dire que je ne manipule pas tous les jours des PODs.



    Citation Envoyé par 3DArchi Voir le message
    (3)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    typedef boost::variant<ecole_1,ecole_2> cours;
    Je connaissais pas du tout, merci beaucoup

  15. #15
    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
    Par défaut
    Citation Envoyé par méphistopheles Voir le message
    Je suppose que tu voulais écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct cours
    {
       virtual ~cours()=0;
    };
    Oui. copier/coller toujours un peu rapide
    Citation Envoyé par méphistopheles Voir le message
    Je confirme... par contre, j'avais complètement oublié que ça existait encore les unions... faut dire que je ne manipule pas tous les jours des PODs.
    En les réduisant aux types triviaux, je pense que les unions à la 'C' sont tombées un peu en désuétude en C++. Avec C++0x qui permet de faire des unions avec n'importe quel type (y compris des classes tout ce qu'il y a de moins trivial), on devrait se réinterresser à ces unions.
    Citation Envoyé par méphistopheles Voir le message
    Je connaissais pas du tout, merci beaucoup
    Boost.Variant permet de faire des unions sur des types non triviaux ... en attendant C++0x

  16. #16
    Membre Expert
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    En les réduisant aux types triviaux, je pense que les unions à la 'C' sont tombées un peu en désuétude en C++. Avec C++0x qui permet de faire des unions avec n'importe quel type (y compris des classes tout ce qu'il y a de moins trivial), on devrait se réinterresser à ces unions.
    Ha ? je savais qu'il permettait de rendre triviales des classes "homemade" (avec la =default), mais je savais pas pour le union.

    Va falloir que je m'abime encore un peu le yeux dans les drafts moi ....

  17. #17
    Membre du Club
    Inscrit en
    Février 2010
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 9
    Par défaut
    je n'en peux plus.... Aucune des 3 propositions adoptées par ce satané compilateur... (je suis sous C++ Builder 2010

    Avec comme message commun aux 3 méthodes proposées:

    [BCC32 Erreur] unit1.h(530): E2034 Impossible de convertir 'MYSTRUCT1_S *' en 'auto_ptr<MYSTRUCT_S>'
    [BCC32 Erreur] unit1.h(537): E2034 Impossible de convertir 'MYSTRUCT2_S *' en 'auto_ptr<MYSTRUCT_S>'

    Erreur sur ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     std::auto_ptr<MYSTRUCT_S> ret = new MYSTRUCT1_S;
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::auto_ptr<MYSTRUCT_S> ret = new MYSTRUCT2_S;
    ==========================================
    Finalement je pense que la méthode avec union semble la plus adaptée.
    Mais, quelle autre terminologie utiliser alors pour définir ma variable de travail déclarée comme ci-dessous, // dans unit1.cpp - form principale.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static MYSTRUCT_S MyData;
    Je ne peux pas faire çà:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    static  MYSTRUCT1_S   MyData;
    static  MYSTRUCT2_S   MyData;
    et la fonction suivante qui la renvoie: // déclarée aussi dans unit1.cpp mais pouvant être appelée par d'autres unités.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    MYSTRUCT_S* Get_MyData(void) {
    	return(&MyData);  
    };
    /* ici [BCC32 Erreur] unit1.cpp(372): E2316 'MyData' n'est pas un membre de 'MYSTRUCT_S' */
    Merci de me supporter..

  18. #18
    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
    Par défaut
    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
    #include <iostream>
    struct MYSTRUCT_S
    {
       virtual ~MYSTRUCT_S()=0;
    };
    MYSTRUCT_S::~MYSTRUCT_S(){}
     
    struct MYSTRUCT_S1 : public MYSTRUCT_S
    {
       virtual ~MYSTRUCT_S1(){}
    };
    struct MYSTRUCT_S2: public MYSTRUCT_S
    {
       virtual ~MYSTRUCT_S2(){}
    };
    #include <memory>
    int main()
    {
       std::auto_ptr<MYSTRUCT_S> ptr (new MYSTRUCT_S1);
       ptr = std::auto_ptr<MYSTRUCT_S>(new MYSTRUCT_S2);
       return 0;
    }

  19. #19
    Membre du Club
    Inscrit en
    Février 2010
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 9
    Par défaut
    BINGO !

    Juste un problème: Le sizeoff() me renvoie 4 octets supplémentaires dans les structures, et çà n'arrange pas les choses, parce que plusieurs autres procédures utilisent le sizeoff(MyData), en particulier pour sauvegarder le fichier après modifications des données. Où se situent ces 4 octets supplémentaires ?

    Ai-je bien placé les éléments des structures ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    struct MYSTRUCT_S1 : public MYSTRUCT_S
    {
       /*
        ici déclarations des membres
       .
       .
       */
       virtual ~MYSTRUCT_S1(){}
    };
    ICI Sizeoff(MYSTRUCT_S1) me donne 8960

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef struct
    {
       /*
        ici les mêmes déclarations des membres
       .
       .
       */
    } MYSTRUCT_S1;
    ICI Sizeoff(MYSTRUCT_S1) me donne 8956

    Idem pour MYSTRUCT_S2 ( 5880 ret 5876)

    Autres chose:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    int main()
    {
       std::auto_ptr<MYSTRUCT_S> ptr (new MYSTRUCT_S1);
       ptr = std::auto_ptr<MYSTRUCT_S>(new MYSTRUCT_S2);
       return 0;
    }
    Je suppose que vous vouliez écrire: ptr = std::auto_ptr<MYSTRUCT_S>(new MYSTRUCT_S1);

    Et enfin, ma variable de travail et ma fonction Get_MyData(), svp ?
    MERCI !

  20. #20
    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
    Par défaut
    Citation Envoyé par ilovec Voir le message
    Juste un problème: Le sizeoff() me renvoie 4 octets supplémentaires dans les structures, et çà n'arrange pas les choses, parce que plusieurs autres procédures utilisent le sizeoff(MyData), en particulier pour sauvegarder le fichier après modifications des données. Où se situent ces 4 octets supplémentaires ?
    vtable est le mot-clé (en fait, vpointer) : les tables virtuelles
    Citation Envoyé par ilovec Voir le message
    Autres chose:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    int main()
    {
       std::auto_ptr<MYSTRUCT_S> ptr (new MYSTRUCT_S1);
       ptr = std::auto_ptr<MYSTRUCT_S>(new MYSTRUCT_S2);
       return 0;
    }
    Je suppose que vous vouliez écrire: ptr = std::auto_ptr<MYSTRUCT_S>(new MYSTRUCT_S1);
    Non. C'est bien pour te montrer qu'avec l'héritage tu manipules une variable de type statique MYSTRUCT_S qui peut avoir un type dynamique MYSTRUCT_S1 ou MYSTRUCT_S2. Bref, tu travailles avec l'abstraction MYSTRUCT_S qui peut être réalisée par MYSTRUCT_S1 ou MYSTRUCT_S2 selon ton besoin.
    Citation Envoyé par ilovec Voir le message
    Et enfin, ma variable de travail et ma fonction Get_MyData(), svp ?
    Euh. La mauvaise réponse : le singleton ? La bonne : dépend de ta conception et à quoi sert ta variable.

Discussions similaires

  1. Réponses: 1
    Dernier message: 03/05/2011, 18h02
  2. Réponses: 3
    Dernier message: 08/12/2009, 19h44
  3. Correspondance entre deux vecteurs de taille différente
    Par MisterK dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 31/03/2008, 17h07
  4. [FEDORA] choix entre différente architecture
    Par PC81 dans le forum RedHat / CentOS / Fedora
    Réponses: 1
    Dernier message: 17/03/2007, 21h38
  5. [XML] Choix entre différentes structures de fichier XML
    Par loic_86 dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 21/02/2007, 05h39

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