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 :

Problème NULL vs ZERO


Sujet :

C++

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Février 2008
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 10
    Par défaut Problème NULL vs ZERO
    Bonjour à tous et merci d'avance pour votre aide,

    Voila, j'ai un soucis subtil avec NULL dans un template.
    Ce template est une collection qui contient des structures de type <T>

    Dans ce template on peut se deplacer en avant, en arrière, etc..
    Il contient une structure qui correspond au déplacement courant (mCurrent).

    Quand c'est necessaire, l'utilisateur peut acceder aux données stockées via GetData() et recupérer les données, comme ci dessous.

    Toutefois, dans le cas ou l'index n'est pas valide, je ne sais pas quoi retourner. cas ou mCurrent = 0.

    Si je renvois zero, le compilateur n'est pas content et va me dire un message du genre lol

    "error C2440: cannot convert from 'void *' to 'char *&'"

    Si à la place de renvoyer zéro, je renvoie (void *)0, c'est le même problème. et je ne me vois pas renvoyer une instance de T quand même.

    Est-ce que ça pourrait être un problème de désign du code?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    T &Current()
    {
         if(mCurrent != 0)
    	return mCurrent->GetData();
        return (void *)0; // meme pbm avec return 0;
    }
    }

  2. #2
    screetch
    Invité(e)
    Par défaut
    tu ne peux pas renvoyer 0 lorsque tu veux renvoyer une reference. les references sont forcement attachées a un objet.

    si tu souhaites renvoyer 0 tu dois renvoyer un pointeur

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Février 2008
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 10
    Par défaut
    Citation Envoyé par screetch Voir le message
    tu ne peux pas renvoyer 0 lorsque tu veux renvoyer une reference. les references sont forcement attachées a un objet.

    si tu souhaites renvoyer 0 tu dois renvoyer un pointeur
    Certes mais j'ignore le contenu du template, c'est l'utilisateur qui décide ce qu'il doit être stocké dedans ? Peut être faut il déclencher une exception dans ce cas??

  4. #4
    screetch
    Invité(e)
    Par défaut
    oui c'est aussi une bonne solution.

  5. #5
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    Pourquoi lancer l'exception dans ton cas??? Il te suffit simplement comme te l'a dit screetch de renvoyer un pointeur null. Eventuellement, tu peux ensuite générer une exception en amont si c'est vraiment nécessaire pour ma part je préfère utiliser des asserts dans ce genre de situation ou l'accès à une structure de données doit être suffisement rapide et donc en évitant au maximum les tests qui peuvent être évités... Enfin c'est mon opinion...

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Février 2008
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 10
    Par défaut
    ha j'avais pas vu ton message babar

    renvoyer un pointeur systematiquement?

    disons que je sais pas ce que l'utilisateur place dans le template

    ca peut etre des pointeurs, des int, des structures entieres, etc
    si je renvoie un pointeur sur un pointeur ca risque pas de poser pbm?

    mCurrent->GetData()

    et je transforme T &GetData() en T *GetData()

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    T *GetData()
    {
       return (T *) &Data ?
    }

    je repasse ce soir

    a+

  7. #7
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    ca peut etre des pointeurs, des int, des structures entieres, etc
    si je renvoie un pointeur sur un pointeur ca risque pas de poser pbm?
    Pour les structures, classes... aucun problème tu peux renvoyer un pointeur, si tu souhaite pouvoir gérer aussi des pointeurs je dirai qu'il faut spécialiser ton template
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template <typename T>
    struct Structure<T *>
    {
         T GetData();
    }
    Je n'ai pas encore eu à utiliser ce genre de spécialisation donc je ne suis pas sur a 100% de mon code donc a vérifier...

    Pour ta classe non spécialisée en effet ta fonction est T *GetData(). Il me semble que ca donnerait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    T *GetData()
    {
       return ( (mCurrent!=NULL) ? mCurrent->GetData() : NULL )
    }
    ...Tout simplement

    Même dans ce cas il te reste un test pour récupérer ta donnée, si tu souhaite utiliser ton container pour une grande quantité d'objets revoie peut-être le design pour essayer de supprimer ce test (pourquoi pas remplacer par un assert justement) mais la je n'en sais pas suffisement sur ce que tu souhaite faire donc ce n'est qu'une supposition!

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Février 2008
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 10
    Par défaut
    merci pour ta reponse

    mais concernant la donnée renvoyée par getdata()

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    T * GetData()
    {
         return &mData;
    }
    return &mData serait suffisant dans tous les cas? si mData est par exemple un pointeur ou valeur de int ou meme structure?

    y a pas une conversion a faire dans le cas ou je stocke des <char *>

    est il suffisant d'ecrire char * c = GetData() en supposant qu'il me renvoie un char *& ? lol


    merci pour ton aide

  9. #9
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    La solution que je t'ai proposée est une manière "propre"(à mon sens) de gérer les pointeurs. Dans ton cas, la fonction marchera très bien pour les pointeurs ou n'importe quelle structure en revanche tu retournera parfois un pointeurs de pointeur et d'autre fois un pointeur sur la structure gérer(T ou *T). D'autre part, si dans la suite de ton code tu dois faire quelques chose du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MonContener.GetData()->UneFonction
    alors ta fonction n'est plus correct pour les pointeurs...
    EDIT : J'ai zapé une partie de ta réponse...'sui fatigué
    pour être plus clair voila l'exemple complet
    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
    template <typename T>
    struct Structure
    {
         T * GetData() {return &mData;}
     
    	 T mData;
    };
     
    //Spécialisation pointeur :
    template <typename T>
    struct Structure<T*>
    {
         T * GetData() {return mData;}
     
    	 T * mData;
    };
     
    int main()
    {
    	Structure<char> s1;
    	Structure<char*> s2;
     
    	char * c1 = s1.GetData();
    	char * c2 = s2.GetData();
     
    	return 0;
    }
    y a pas une conversion a faire dans le cas ou je stocke des <char *>

    est il suffisant d'ecrire char * c = GetData() en supposant qu'il me renvoie un char *& ? lol
    Attention de ne pas confondre char ** et char *& dans ton cas tu renvoie un char ** donc le compilo ne va pas apprécier

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Février 2008
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 10
    Par défaut
    merci ca marche...

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Février 2008
    Messages : 9
    Par défaut Problème NULL vs ZERO
    Hello, bien que tu as trouvé réponse, il y a une autre façon de gérer les reference dites "invalide": La solution est tres simple en deux étapes:

    1 - La classe qui va fournir une instance "invalide d'elle-même"
    Soit en exemple un objet qui gère les opérations sur une coordonnée:

    Bien entendu, une coordonnee en soit peut avoir n'importe quelles valeurs
    sans savoir par celle-ci si elle est valide. - Alors une et une seule instance
    [NUL] peut etre retournee en reference lorsque une erreur survient invalidant
    l'operation.

    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
     
    \*!
        \class pxy 
        \brief cette classe gere une coodonnee xy
    */
     
    class pxy{
    public:
        pxy(){} 
        pxy (int x, int y ){ ... blah }
     
        .
        .
        .
        bool operator !() { return this == &pxy::NUL ; }
        .
        .
        .
     
    private:
        // NUL doit etre privee pour eviter de le modifier par "accident" :-)
        static pxy NUL;
    }; // classe pxy fin
     
     
    // implementation de la classe pxy ( pxy.cpp ou le meme .h )
     
    pxy pxy::NUL; // peu importe comment NUL est initialisee, c'est l'instance qui compte
    .
    . 
     
     
    // Example de situation invalide:
    .
    .
    .
        pxy xy = pxy(-4, 500);
        pxy gxy;
        if(!( gxy = ToGlobal( xy ) )){
            // voila, ici ToGlobal a invalidé gxy en y retournant la valeur de pxy::NUL;
            return... 
        }
     
     
    //fin
    Bon mon apport n'a peut-être plus ...rapport... mais c'est bien ce que je fais
    dans quelques projets dans cette situation particulière.

  12. #12
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Tu sais, contre les modifications "par accident", const est plus efficace que private...

    Et permet aux utilisateurs de la classe de s'en servir...
    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.

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Février 2008
    Messages : 9
    Par défaut const vs private
    J'ai pas pris le temps de réfléchir, mais à la base la fonction ou methode qui va retourner l'instance peut avoir ce prototype:

    const pxy& ToGlobal(...);

    ce qui va revenir au meme...
    Pour les erreurs de manipulations -- c'est une autre histoire...

    Merci de m'avoir corriger

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

Discussions similaires

  1. enlever valeur null ou zero dans un graph
    Par dawaman dans le forum Excel
    Réponses: 9
    Dernier message: 22/09/2011, 09h21
  2. Problème Null Pointer Exception
    Par bitter00 dans le forum Servlets/JSP
    Réponses: 5
    Dernier message: 18/08/2011, 13h04
  3. Problème null pointer applet interne
    Par ulquiorra dans le forum Applets
    Réponses: 1
    Dernier message: 17/06/2010, 23h52
  4. [EJB3] [JBoss] Problème null pointer
    Par MattA184575 dans le forum Java EE
    Réponses: 2
    Dernier message: 08/01/2009, 19h22
  5. remplacer null par zero
    Par haykelFST dans le forum SAP Crystal Reports
    Réponses: 1
    Dernier message: 16/12/2008, 10h24

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