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 :

Initialisation de classe Membre


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Mars 2008
    Messages
    63
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 63
    Par défaut Initialisation de classe Membre
    Bonjour je suis débutant en C++ et j'ai un petit probleme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    edge.cpp: In constructor ‘Edge::Edge(const Vertex&, const Vertex&)’:
    edge.cpp:8: erreur: no matching function for call to ‘Vertex::Vertex()’
    ../include/vertex.hpp:8: note: candidats sont: Vertex::Vertex(float, float, float)
    ../include/vertex.hpp:4: note:                 Vertex::Vertex(const Vertex&)
    edge.cpp:8: erreur: no matching function for call to ‘Vertex::Vertex()’
    ../include/vertex.hpp:8: note: candidats sont: Vertex::Vertex(float, float, float)
    ../include/vertex.hpp:4: note:                 Vertex::Vertex(const Vertex&)
    J'image que cela est un problème d'initialisation de mes membre _v1 et _v2. Je vous passe 4 fichier de mon code vertex.cpp et vertex.hpp qui st en fait des points avec les coordonnées en 3 dimensions et edge.cpp et edge.hpp qui sont des arretes reliant certains de ces points.

    vertex.hpp
    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
     
    #ifndef VERTEX_HPP
    #define VERTEX_HPP
     
    class Vertex {
     
    public:
      // Constructeur
      Vertex (float x, float y, float z);
     
      // Accesseur en lecture seulement
      float x () const;
      float y () const;
      float z () const;
     
    private:
      float _x, _y, _z;
     
    };
     
    // Opérateur de comparaison
    bool operator== (const Vertex &v1, const Vertex &v2);
    bool operator!= (const Vertex &v1, const Vertex &v2);
    bool operator>  (const Vertex &v1, const Vertex &v2);
    bool operator<= (const Vertex &v1, const Vertex &v2);
    bool operator<  (const Vertex &v1, const Vertex &v2);
    bool operator>= (const Vertex &v1, const Vertex &v2);
     
    #endif /* VERTEX_HPP */
    vertex.cpp
    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
     
    #include "vertex.hpp"
     
    /*
      Constructeur :
    */
     
    Vertex::Vertex (float x, float y, float z) {
      this->_x = x;
      this->_y = y;
      this->_z = z;
    }
     
    /*
      Accesseur :
      en lecture seulement
    */
     
    float Vertex::x () const {
      return _x;
    }
     
    float Vertex::y () const {
      return _y;
    }
     
    float Vertex::z () const {
      return _z;
    }
     
    /*
      Opérateur :
    */
     
    bool operator== (const Vertex &v1, const Vertex &v2) {
      return ((v1.x() == v2.x()) &&
    	  (v1.y() == v2.y()) &&
    	  (v1.z() == v2.z()));
    }
     
    bool operator!= (const Vertex &v1, const Vertex &v2) {
      return (!(v1 == v2));
    }
     
    bool operator>  (const Vertex &v1, const Vertex &v2) {
     
      if (v1.x() > v2.x())
        return true;
      else if (v1.x() < v2.x())
        return false;
     
      if (v1.y() > v2.y())
        return true;
      else if (v1.y() < v2.y())
        return false;
     
      if (v1.z() > v2.z())
        return true;
      else if (v1.z() < v2.z())
        return false;
     
      return false;
    }
     
    bool operator<= (const Vertex &v1, const Vertex &v2) {
      return (!(v1 > v2));
    }
     
    bool operator<  (const Vertex &v1, const Vertex &v2) {
     
      if (v2.x() > v1.x())
        return true;
      else if (v2.x() < v1.x())
        return false;
     
      if (v2.y() > v1.y())
        return true;
      else if (v2.y() < v1.y())
        return false;
     
      if (v2.z() > v1.z())
        return true;
      else if (v2.z() < v1.z())
        return false;
     
      return false;
    }
     
    bool operator>= (const Vertex &v1, const Vertex &v2) {
      return (!(v1 < v2));
    }
    edge.hpp
    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
     
    #ifndef EDGE_HPP
    #define EDGE_HPP
     
    #include "vertex.hpp"
     
    class Edge {
     
    public:
      // Constructeur
      Edge (const Vertex &v1, const Vertex &v2);
     
      // Accesseur en lecture seulement
      Vertex point1 () const;
      Vertex point2 () const;
     
    private:
      Vertex _v1;
      Vertex _v2;
    };
     
    // Opérateur de comparaison
    bool operator== (const Edge &e1, const Edge &e2);
    bool operator!= (const Edge &e1, const Edge &e2);
    bool operator>  (const Edge &e1, const Edge &e2);
    bool operator<= (const Edge &e1, const Edge &e2);
    bool operator<  (const Edge &e1, const Edge &e2);
    bool operator>= (const Edge &e1, const Edge &e2);
     
    #endif /* EDGE_HPP*/
    edge.cpp
    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
     
    #include "edge.hpp"
    #include "vertex.hpp"
     
    /* 
       Constructeur :
    */
     
    Edge::Edge (const Vertex &v1, const Vertex &v2) {
      if (v1 < v2) {
        _v1 = v1;
        _v2 = v2;
      }
      else {
        _v1 = v1;
        _v2 = v2;
      }
    }
     
    /*
      Accesseur :
    */
     
    Vertex Edge::point1 () const {
      return _v1;
    }
     
    Vertex Edge::point2 () const {
      return _v2;
    }
     
    /*
      Opérateurs :
    */
     
    bool operator== (const Edge &e1, const Edge &e2) {
      return ((e1.point1() == e2.point1()) && 
    	  (e1.point2() == e2.point2()));
    }
     
    bool operator!= (const Edge &e1, const Edge &e2) {
      return (!(e1 == e2));
    }
    Voila, j'aimerai evidemment que la fonction Edge::point1() renvoie vraiment le vetex correspondant de tel manière à que si on le midifie ca modifie celuiqui était passer en argument dans le constructeur de Edge.

    Merci d'avance si quelqu'un peut m'expliquer rapidement ou si quelqu'un à un exemple de code analogue à l'utilisation que je veux faire de mes classes.

  2. #2
    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,

    Le problème vient du fait que tu n'a pas déclaré (ni défini) de constructeur ne prenant aucun paramètre pour ta classe vertex.

    Or, même si tu ne l'indique pas, le comportement d'un constructeur (celui de ta classe edge en l'occurrence), va commencer par instancier ses membre, et, comme tu ne fournit aucune précision quant à la manière de créer ces membres, le compilateur va chercher la version du constructeur pour le membre qui... ne prend aucun argument et qui, en ce qui concerne Vertex, n'existe pas...

    Ce que tu peux donc faire, étant donné que tu fournis deux références constantes de type vertex à ta classe edge, c'est d'appeler d'office le constructeur par copie (qui est rajouté automatiquement par le compilateur, vu que tu ne l'a pas déclaré par toi même), dans la liste d'initialisation du constructeur de la classe edge, puis de vérifier que v1 et v2 aient bien pris les bonnes valeurs (en inversant au besoin)

    Cela donnerait quelque chose dans le genre de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Edge::Edge(const Vertex& v1, const Vertex& v2):_v1(v1), _v2(v2)
    {
        if(_v2<_v1)
        {
            Vertex temp = _v1;
            _v1 = _v2;
            _v2=temp;
        }
    }
    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

  3. #3
    Membre confirmé
    Inscrit en
    Mars 2008
    Messages
    63
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 63
    Par défaut
    ok merci beaucoup ca compile bien.

  4. #4
    Membre confirmé
    Inscrit en
    Mars 2008
    Messages
    63
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 63
    Par défaut
    Ca compile bien par contre ca ne joue pas un fonctionnalité que je voudrais bien.

    En fait dans le cas ou je modife un vertex dans un edge, cela ne modifie pas le vertex que j'avais passer en argument. Je ne veuxpas que ce soit une copie de l'objet en mais je voudrais que ce soit l'objet lui-meme.

    Je suis completement paumé ca oit pas etre grand chose à fair pour que ca marche.

    Merci d'avance.

  5. #5
    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
    Pour pouvoir t'aider, sur ce coup là, il faudrait que tu nous indiques quelle utilisation tu fais de tes variables de type Edge ou Vertex...

    De manière générale, tu va avoir le choix entre:
    • Manipuler une collection de Vertices, et créer tes Edges sur base des vertices existant ou
    • Manipuler une collection de Edges, et récupérer les vercices de chacune d'elle pour les manipuler "séparément".
    • peut être d'autres solutions.

    La solution adaptée dépendant essentiellement de la nature de l'utilisation que tu fera de tout cela
    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

  6. #6
    Membre confirmé
    Inscrit en
    Mars 2008
    Messages
    63
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 63
    Par défaut
    En faite je voudrais représenter un maillage 3D, une surface composée de nombreux triangles.

    Je veux donc utiliser 4 classes principalement :
    - vertex (mes points)
    - edge (mes arrete de mes triangles)
    - face (mes triangles)
    - maillage (Listes des vertex edges face)

    Si je veux créer les edges au lieu de les calculer à chaque fois c pour pouvoir faire un grand nombre de calcul dessus et gagner du temps en ne les calculant pas au fur et a mesure.

    Maillage possedera donc un lien vers tous les vertex, tous les edges et toutes les faces.
    Mais chaque classe aura un lien vers d'autres classe. En fait vertex possedera la liste des edges et face qui lui sont liés. Je souhaiterai donc que dans le cas ou l'objet vertex v1 de la liste dans le maillage et modifié alors cela et modifié l'objet v2 dans toutes les autres objets correspondant.

    Yaurait pas moyen de créer une sorte de constructeur du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Vertex::Vertex (const Vertex &v) {
      // et la un truc du genre l'objet crée est le meme que l'objet passer en argument
      // comme ca si on modifie l'un ca modifierait l'autre dans le sens ou c'est le même
    }
    Donc voila. Je cherche sur internet des exemples mais bon ...

  7. #7
    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
    Oulala...

    Ici, il est plus que temps de reprendre la fameuse phrase
    si un type a plus d'une responsabilité, c'est qu'il en a trop
    • La seule responasbilité que ton vertex doive avoir, c'est de pouvoir se disposer dans un espace trois dimensions.
    • La seule responsabilité que ton type edge doive avoir, c'est de fournir la position à laquelle il commence et la position à laquelle il s'acheve
    • La seule responsabilité de ta classe Face devrait d'etre de s'assurer que le triangle soit cohérent (en gros, que chaque vertex correspond à un angle de ton triangle)
    • Enfin, la seule responsabilité de ta classe Maillage devrait être de... garder une collection de Face cohérente.

    Tout ce qui sort des quatre responsabilités ci-dessus devrait échoir à d'autres classes.

    Mais, reprenons depuis le début:

    La durée de vie d'un vertex n'a rien à voir avec la durée de vie de l'Edge dans laquelle il se trouve.

    Tu te trouve donc - du point de vue conceptuel - dans le cas d'une agrégation, et non dans le cas d'une composition.

    Cela implique que ta classe Edge doit maintenir... deux pointeurs de type Vertex, et non deux objet de type vertex.

    Elle devrait donc devenir proche 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
    class Edge
    {
        public:
            Edge(Vertex* v1, Vertex* v2):_v1(v1), _v2(v2)
            {
                /* les deux vertices doivent exister */
                assert(_v1!=NULL);
                assert(_v2!=NULL);
                if((*_v1)< (*_v2))
                {
                    /* une autre manière "sympa" d'inverser les adresse de deux
                     * pointeurs
                     */
                    _v1^=_v2;
                    _v2^=_v1:
                    _v1^=_v2;
                }
            }
            ~Edge()
            {
                 /*se contente de mettre les pointeur à NULL */
                 _v1 = NULL;
                 _v2 = NULL;
            }
            Vertex& getV1()
            {
                return *_v1;
            }
            /* la meme en version constante */
            const Vertex& getV1() const
            {
                return *_v1;
            }
     
            Vertex& getV2()
            {
                return *_v2;
            }
            /* la meme en version constante */
            const Vertex& getV2() const
            {
                return *_v2;
            }
            /* autres méthodes utiles */
        private:
            Vertex* _v1;
            Vertex* _v2;
    };
    Ta classe Face sera créée de manière similaire: la durée de vie du vertex n'étant pas liée à celle de la face

    Par contre, il faudra déterminer si la durée de vie des Edge's qui composent ta face est liée à celle de la face (j'ai considéré ici que c'est le cas)
    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 Face
    {
        public:
            /* construisons une face sur base des vertices */
            Face(Vertex* v1, Vertex* v2, Vertex* v3):_v1(v1), _v2(v2), _v3(v3),
                                                     _e1(_v1,v2),_e2(v2_,v3),
                                                     _e3(_v1,_v3)
           {
               /* les trois vertices doivent exister */
               assert(_v1!=NULL);
               assert(_v2!=NULL);
               assert(_v3!=NULL);
               /* il est possible de vouloir trier les trois vertices, 
                * mais cela impliquerait de trier également les trois edge's
                */
           }
            /* ou sur base des edge's sur base des vertices */
            Face(const Edge* e1, const Edge& e2, const Edge& e3)
            :_v1(e1.getV1()), _v2(e2.getV2()), _v3(e3.getV1()),
            _e1(e1),_e2(e2), _e3(e3)
           {
               /* L'existance des vertices est garantie par le fait que les
                * edge's ont été créées 
                */
           }
           /* le destructeur se contente de mettre les pointeurs à NULL
            * (la destruction des edge's est automatique)
            */
          ~Face()
           {
               _v1=NULL;
               _v2=NULL;
               _v3=NULL;
           }
           /* les autres méthodes utiles */
        private:
            /* les trois vertices (des pointeurs) */
            Vertex* _v1;
            Vertex* _v2;
            Vertex* °v3;
            /* les trois edge's associées */
            Edge _e1;
            Edge _e2;
            Edge _e3;
    }
    Pour le maillage, il faudra décider si la durée de vie des faces qu'il contient est liée à celle du maillage en lui-même ou non...

    Ici, j'ai considéré qu'elle l'était.

    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
    class Maillage
    {
        public:
            /* le constructeur ne fait rien */
            Maillage()
            {
            }
            /* le destructeur non plus */
            ~Maillage()
            {
            }
            /* il y a plusieurs manières de demander d'ajouter une face au
             * maillage toutes ne sont pas forcément
             * indispensables nécessaires / utiles /  (en fonction de ce qui
             * existe par ailleurs)
             */
            /* on peut ajouter une face en fournissant trois vertices */
            void addFace(Vertex* v1, Vertex* v2, Vertex* v3)
            {
                /* les trois vertices doivent exister */
                assert(v1!=NULL);
                assert(v2!=NULL);
                assert(v3!=NULL);
                faces.push_back(Face(v1,v2,v3));
            }
            /* en fournissant les trois edges */
            void addFace(const Edge& e1, const Edge& e2, const Edge& e3)
            {
                faces.push_back(Face(e1, e2, e3));
            }
            /* ou en fournissant uen face existante */
            void addFace(const Face& f)
            {
                faces.push_back(f);
            }
            /* les autres méthodes utiles */
        private:
            /* la collection de face (pourrait etre un autre conteneur) */
            std::listFace> faces;
    };
    Enfin, il reste la problématique de la gestion des vertices, dont la durée de vie est dissociée de tout le reste.

    Il s'agira donc de créer une classe dont la seule responsabilité sera de gérer les différents vertices, et plusieurs "Design Patterns" sont envisageables, mais je vais arreter là l'écriture du roman
    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. initialisation des classes membres d'une classe
    Par Krishna dans le forum C++
    Réponses: 2
    Dernier message: 09/05/2008, 20h27
  2. Réponses: 2
    Dernier message: 17/04/2008, 18h23
  3. Réponses: 0
    Dernier message: 25/07/2007, 14h47
  4. Réponses: 3
    Dernier message: 06/01/2007, 14h46
  5. Initialiser une référence membre d'une classe
    Par NicolasJolet dans le forum C++
    Réponses: 2
    Dernier message: 18/03/2006, 12h14

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