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 :

Accéder à des attributs pointeurs d'une classe


Sujet :

C++

  1. #1
    Membre averti
    Homme Profil pro
    Architecte matériel
    Inscrit en
    Juin 2015
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte matériel

    Informations forums :
    Inscription : Juin 2015
    Messages : 31
    Par défaut Accéder à des attributs pointeurs d'une classe
    Bonjour,
    Je n'arrive pas à comprendre comment accéder au attribut de ma classe qui sont des pointeurs
    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
     
    class Triangle{
    public:
    	Triangle();
    	Triangle(Vec3f a, Vec3f b, Vec3f c);
    	Triangle(Vec3i indices, std::vector<Vec3f> &vertexList);
    	Box getBoundingBox()const; 
    	friend std::ostream& operator << (std::ostream &s, const Triangle &t)
        {
    		return s << *t.p1 << "\n" << *t.p1 << "\n" << *t.p2;// ne donne pas les bonne valeur
        }
    //protected:
    	Vec3f *p0;
    	Vec3f *p1;
    	Vec3f *p2;
    };
    j'ai essayé
    t.(*p1) ça ne compile pas
    t->p1 ça non plus

  2. #2
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    C'est *(t.p1).
    Mais en théorie, *t.p1 doit donner la même valeur. C'est même la raison pour laquelle t->p1 équivaut à (*t).p1.
    Or t n'est pas un pointeur ou un objet définissant operator*().

    t.(*p1) n'est pas syntaxiquement valable.
    L'argument droit de l'opérateur . n'est pas une valeur, mais un identificateur qui doit être connu à la compilation

    Le plus proche est t.*p1, qui n'a rien à voir car p1 serait alors un pointeur vers un membre de triangle, tel que int triangle::*, par exemple.
    Ce p1-là ne serait d'ailleurs pas membre de t.

    Et si ca ne donne pas les bonnes valeurs, c'est peut-être parce que tu affiches deux fois p1, mais pas p0.
    Ou alors, comme tout bon pointeur, parce qu'il ne pointe pas sur ce que tu crois.

  3. #3
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Question conception, si ton triangle utilise des pointeurs vers ses sommets, c'est que ceux-ci sont manipulés comme des points autonomes.
    Si c'est bien le cas, il y a tout intérêt à avoir un type nommé pour l'occasion: un Point ou Point3d.
    Ca peut tout à fait être fait par un typedef Vec3f Point3d.

    Si au contraire, ce n'est pas le cas, supprime donc ces pointeurs.

  4. #4
    Membre averti
    Homme Profil pro
    Architecte matériel
    Inscrit en
    Juin 2015
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte matériel

    Informations forums :
    Inscription : Juin 2015
    Messages : 31
    Par défaut
    Merci leternel

    Oui en fait mon pointeur ne pointe pas sur la bonne chose, on dirait que lors de l'appel cout << t << endl;
    le t n'est pas passé en paramètre, pourtant pour mes autres classes j'avais fait la même méthode et ça marchait bien.

    En fait je dispose d'une liste de points, car les triangles représente un maillage 3D. Les points peuvent etre contenu dans plusieurs triangles, donc cela m'économise de la mémoire de mettre des pointeurs. J'ai bon ?

  5. #5
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Ca peut, mais dans ce cas, j'espère que ta liste est un std::vector.
    Et comme je te le disais, donne un nom explicite à ton type de point.

    Cela t'aidera à garantir l'intégrité de ton code, et à lui donner un sens clair.
    De même, tu pourrais envisager d'utiliser des références plutot que des pointeurs.
    Je me demande aussi si tu ne veux pas des pointeurs/références vers des constantes.

    à mon goût personnel, ca donnerait ceci:

    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
    class Triangle{
    public:
    	//en passant par des références, je sais que les pointeurs ne seront pas nuls.
    	//par contre, il faut un vrai commentaire pour expliquer que tu prends des adresses.
    	//il vaudrait probablement mieux utiliser des indices du tableaux de Point
    	Triangle(Point const& a, Point const& b, Point const& c) {
    		points[0]=&a;
    		points[1]=&b;
    		points[2]=&c;
    	}
    	Triangle(Vec3i const& indices, std::vector<Point> const& vertexList);
    	Box getBoundingBox() const;
    	friend std::ostream& operator << (std::ostream & s, Triangle const& t) {
    		return s << t.p1() << '\n' << t.p2() << '\n' << t.p2();
    	}
     
    	Point const& p1() const {return *points[0];}
    	Point const& p2() const {return *points[1];}
    	Point const& p3() const {return *points[2];}
    private:
    	Point *points[3];
    };
    Du coup, j'ai vu ton bug!
    Le constructeur à trois points prend ses arguments sans pointeur ni référence: donc, tu prends l'adresse de variables locales, détruite à la fin de l'appel au constructeur.

    Une grande règle du C++: "primitif ou const&".

  6. #6
    Membre averti
    Homme Profil pro
    Architecte matériel
    Inscrit en
    Juin 2015
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte matériel

    Informations forums :
    Inscription : Juin 2015
    Messages : 31
    Par défaut
    oui c'est un vector, c'est fait pour le point3d
    Du coup là ça commence à me dépasser ^^, le const& renvoie une "référence constante" ? c'est quoi la différence entre ça et ne rien mettre ?

    Bien vu pour le constructeur ! merci je pense pas que je l'aurais trouvé tout seul ^^

    Pour l'instant j'ai mis ça est ça marche :

    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
     
    #ifndef TRI
    #define TRI
    #include <vector>
    #include "geometry.h"
    #include "box.h"
    class Triangle{
    public:
    	Triangle();
    	Triangle( Point3D *a, Point3D *b, Point3D *c);
    	Triangle(indPointsTriangle indices, std::vector<Point3D> &vertexList);
    	Box getBoundingBox()const; 
    	friend std::ostream& operator << (std::ostream &s, const Triangle &t)
        {
    		return s << *(t.p0) << "\n" << *(t.p1) << "\n" << *(t.p2);
        }
    //protected:
    	Point3D *p0;
    	Point3D *p1;
    	Point3D *p2;
    };
    #endif
    ton code c'est pour avoir une écriture plus propre que *(t.p0) ?

  7. #7
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Mon code, c'est pour empecher quiconque d'utiliser mon pointeur.

    L'usage des références constantes (constant references) est essentiel!
    Cela permet de au compilateur de ne pas copier l'objet désigné.
    C'est un gain souvent considérable en mémoire, en temps et en surete.

    Sans compter ce qui ne peux pas être copié, comme un flux ou une connexion.

    En résumé des cours/tutos à lire sur les sujets, ton code doit normalement être bourré de fonctions constantes et de références constantes.

    Avec ton code, on peut donner un pointeur nul, ca va être drole

  8. #8
    Membre averti
    Homme Profil pro
    Architecte matériel
    Inscrit en
    Juin 2015
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte matériel

    Informations forums :
    Inscription : Juin 2015
    Messages : 31
    Par défaut
    ok, je le sais bien mais lorsque je passe par des référence const le compilo me met :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Triangle::Triangle(Point3D const& a, Point3D const& b, Point3D const& c) {
    		points[0]=&a;
    		points[1]=&b;
    		points[2]=&c;
    }
    Error: impossible d'assigner une valeur de type "const Point3D*" à une entité de type "Point3D*"

  9. #9
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    oups, pardon, c'est un tableau de pointeur de points constant, qu'il faut: Point const *points[3].

  10. #10
    Membre averti
    Homme Profil pro
    Architecte matériel
    Inscrit en
    Juin 2015
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte matériel

    Informations forums :
    Inscription : Juin 2015
    Messages : 31
    Par défaut
    ok je comprend mieux cette phrase mtn ^^ merci
    Je me demande aussi si tu ne veux pas des pointeurs/références vers des constantes.

  11. #11
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    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 397
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Triangle::Triangle(Point3D const& a, Point3D const& b, Point3D const& c) {
    		points[0]=&a;
    		points[1]=&b;
    		points[2]=&c;
    }
    Euh, très franchement, dans ce cas précis, j'éviterais les références et passerais franchement des pointeurs.
    Au niveau compréhension du code, les références en paramètre n'ont pas vraiment de connotation de durée de vie excédant la fonction appelée.

    Si J. Random Programmer voit un tel prototype: Triangle(Point3D const& a, Point3D const& b, Point3D const& c), il va s'imaginer que le constructeur fait des copies, et qu'il n'a donc pas à se soucier de la durée de vie des objets référencés!

    D'ailleurs, d'une manière générale, si tu as à prendre l'adresse d'un objet passé par référence, c'est généralement soit que tu es réduit à interagir avec du code C, soit qu'il y a un problème.
    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.

  12. #12
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    C'est un peu le problème d'OpenGL, c'est du code C

  13. #13
    Membre averti
    Homme Profil pro
    Architecte matériel
    Inscrit en
    Juin 2015
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte matériel

    Informations forums :
    Inscription : Juin 2015
    Messages : 31
    Par défaut
    C'est un peu le problème d'OpenGL, c'est du code C
    Je n'utilise pas openGL ^^

    D'ailleurs, d'une manière générale, si tu as à prendre l'adresse d'un objet passé par référence, c'est généralement soit que tu es réduit à interagir avec du code C, soit qu'il y a un problème.
    En fait pour économiser de la mémoire, j'utilise des pointeurs pour les points du triangle car comme il s'agit d'un maillage triangulaire, un point peut être utilisé par plusieurs tirangles à la fois. Du coup je dispose de ma liste des points dans un vector et de ma liste des triangles dans un vector également.

  14. #14
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    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 397
    Par défaut
    Citation Envoyé par romainprogdebutant Voir le message
    En fait pour économiser de la mémoire, j'utilise des pointeurs pour les points du triangle car comme il s'agit d'un maillage triangulaire, un point peut être utilisé par plusieurs tirangles à la fois. Du coup je dispose de ma liste des points dans un vector et de ma liste des triangles dans un vector également.
    Mais dans ce cas, j'utiliserais des pointeurs tout du long, sans les déguiser en référence dans les paramètres de ma fonction.
    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.

  15. #15
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,
    Citation Envoyé par Médinoc Voir le message
    Mais dans ce cas, j'utiliserais des pointeurs tout du long, sans les déguiser en référence dans les paramètres de ma fonction.
    D'autant plus que, comme il s'agit du constructeur d'un objet, peu importe au final la manière dont il obtiendra l'adresse de chacun des points : si, pour une raison ou une autre le triangle "survi" à la liste des points, tu seras toujours dans la mouise
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

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

Discussions similaires

  1. Réponses: 15
    Dernier message: 13/03/2014, 18h04
  2. [PHP 5.2] Accéder à un attribut statique d'une classe fille
    Par Bacteries dans le forum Langage
    Réponses: 2
    Dernier message: 25/01/2009, 20h55
  3. Réponses: 4
    Dernier message: 16/03/2008, 18h06
  4. Réponses: 4
    Dernier message: 28/03/2007, 22h23
  5. Pointeur sur des fonctions membres d'une classe
    Par Muetdhiver dans le forum C++
    Réponses: 3
    Dernier message: 15/02/2006, 11h35

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