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 :

Constructeur et objet


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2013
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2013
    Messages : 70
    Points : 38
    Points
    38
    Par défaut Constructeur et objet
    Bonjour,

    je fais une classe segment et je voudrais mettre deux points dedans
    (pour créer un segment). Le problème est que je souhaite faire un
    constructeur qui ressemble à ça(code du bas)
    Comme ça dans mon main je fais juste ce qu'il y'a dans le 1er code (je crée deux points que je mets dans le segment)
    Et ce que j'ai fais ne marche pas, j'ai certains doute sur le constructeur de segment
    mais je vois pas comment faire autrement...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        Point monP1(1,1);
        Point monP2(2,2);
        Segment monSeg(monP1,monP2);
    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 DEF_POINT
    #define DEF_POINT
     
    #include<string>
    #include "Forme.h"
    #include "Point.h"
     
    using namespace std;
     
    class Segment
    {
    public:
     
        Segment(Point m_p1,Point m_p2):
        {
        p1=m_p1;
        p2=m_p2;
        }
     
     
    private:
        Point p1;
        Point p2;
        long longueurSegment;
     
    };
     
    #endif

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 628
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 628
    Points : 10 553
    Points
    10 553
    Par défaut
    Et ce que j'ai fais ne marche pas
    Plus de précisions

    Sinon, il y a 2 détails:
    • Tes 2 points sont passés par copie et non par référence. Tu utilises le C++11?
    • Est-ce que tu as surchargé dans ta classe Point l'opérateur d'affectation Point& Point::operator=(const Point& other);?


    Ou alors passe par la liste d'initialisation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        Segment(const Point& m_p1, const Point& m_p2): p1(m_p1), p2(m_p2) {}

  3. #3
    Membre chevronné Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Points : 2 160
    Points
    2 160
    Par défaut
    Citation Envoyé par foetus Voir le message
    Est-ce que tu as surchargé dans ta classe Point l'opérateur d'affectation Point& Point::operator=(const Point& other);?
    Normalement pour une classe Point (aucun pointeur en donnée membre), le compilateur génère le constructeur par copie et l'opérateur d'affectation lui-même et ils font la bonne chose.

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2013
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2013
    Messages : 70
    Points : 38
    Points
    38
    Par défaut
    je ne sais pas si j'utilise le c++11 et je n'ai pas surchargé point.

    Pour plus de précision mon problème est que j'ai comme message d'erreur

    error 'segment' was not declared in this scope
    error expected ';' before 'monSeg'

    erreur absolument incompréhensible vu que dans le main j'ai ça

    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
     
    #include <iostream>
    #include<string>
     
    #include "Forme.h"
    #include "Cercle.h"
    #include "Rectangle.h"
    #include "Point.h"
    #include "Segment.h"
     
    using namespace std;
     
    int main()
    {
     
        Point monP1(1,1);
        Point monP2(2,2);
        Segment monSeg(monP1,monP2);
     
        return 0;
    }

  5. #5
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Points : 1 211
    Points
    1 211
    Par défaut
    Dans Segment.h, remplace DEF_POINT dans les #ifndef et #define en début de fichier par DEF_SEGMENT.

    Edit: je vais quand même expliquer un minimum :
    Dans ton main.cpp tu inclus Point.h et Segment.h, or dans Point.h tu fais un include guard (#ifndef et #define au début) avec la macro DEF_POINT. Lorsque le prépocesseur passe ensuite à Segment.h, comme ta macro est déjà définie, le contenu du fichier est ignoré. Conséquence, ta classe Segment n'est pas définie, il ne sait pas ce que c'est, et te dit qu'il s'attendait à un point-virgule.

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2013
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2013
    Messages : 70
    Points : 38
    Points
    38
    Par défaut
    ah oui mince, j'avais pas fait attention à ça ...

    merci

  7. #7
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    salut,
    Citation Envoyé par foetus Voir le message
    Plus de précisions

    Sinon, il y a 2 détails:
    • Est-ce que tu as surchargé dans ta classe Point l'opérateur d'affectation Point& Point::operator=(const Point& other);?
    Citation Envoyé par Ehonn Voir le message
    Normalement pour une classe Point (aucun pointeur en donnée membre), le compilateur génère le constructeur par copie et l'opérateur d'affectation lui-même et ils font la bonne chose.
    En fait, cela va même plus loin que cela...

    La forme canonique orthodoxe de Coplien nous indique que tous les types devraient au minimum disposer de quatre éléments:
    1. Un constructeur par défaut MaClasse()
    2. un opérateur d'affectation MaClasse & operator = (MaClasse const &)
    3. un constructeur de copie MaClasse(MaClasse const &)
    4. un destructeur ~MaClasse()

    La norme nous garanti que le compilateur générera automatiquement ces quatre éléments si on ne lui donne aucune raison de le faire.

    Par exemple, si on ne définit aucun constructeur prenant un (ou plusieurs) argument(s), le compilateur générera automatiquement le constructeur par défaut, mais, si on défini un constructeur comme, par exemple Point(int , int), le compilateur ne générera pas le constructeur par défaut (mais générera malgré tout le constructeur de copie, l'opérateur d'affectation et le destructeur).

    Ce qui se passe, c'est que le comportement qui sera automatiquement implémenté par le compilateur lorsqu'il génère ces fonctions est parfaitement valide tant que la classe n'utilise pas de ressources dynamiques. Tu n'as donc absolument pas besoin de définir toi-même le constructeur de copie, l'opérateur d'affectation ni pour la classe Point, ni pour la classe Segment, car il n'y a aucune ressource allouée dynamiquement

    Ensuite, il y a le problème de ce que l'on appelle la sémantique des classes : Certaines classes (comme la classe Point et / ou la classe Segment) ont ce que l'on appelle une sémantique de valeur (voir FAQ) car il est tout à fait possible de trouver, à un instant T donné de l'exécution, plusieurs objets de type Points ou plusieurs objets de type Segment qui présentent exactement les mêmes valeur.

    La forme canonique orthodoxe de Coplien s'applique exclusivement à ce genre de classe.

    D'autres classes par contre ont ce que l'on appelle une sémantique d'entité (voir FAQ) parce qu'il est dangereux, à un instant T donné de l'exécution, de retrouver plusieurs objets présentant exactement les mêmes valeurs. C'est, par exemple, le cas de classe comme FormeGeometrique, Personnage, Sort et autres. Les principales caractéristiques de ces classes sont d'être des candidats idéales à l'héritage public (FormeGeometrique peut être dérivé en Carre, Rectangle, ..., Personnage peut être dérivé en PersonnageJoueur et en PersonnageNonJoueur, Sort peut ... bon, allez, tu auras compris le principe ), et de n'être ni copiable ni affectables.

    Pour ce genre de classe, il faut donc veiller à faire en sorte de refuser toute tentative de copie ou d'affectation. C++11 nous facilite la tâche en nous permettant désormais de déclarer l'opérateur d'affectation et le constructeur de copie comme étant delete, ce qui indique explicitement au compilateur qu'il ne doit pas générer ces éléments
    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

  8. #8
    Membre chevronné Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Points : 2 160
    Points
    2 160
    Par défaut
    Et ici, la classe Point a probablement des types primitifs (comme int) en donnée membre (probablement x et y) et donc le constructeur par défaut généré par le compilateur ne fait pas la bonne chose pour moi car il ne va pas initialiser à 0 ces attributs.

  9. #9
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    @koala01: Un peu dépassé la forme canonique a 4 éléments. Tu pourrais inclure les constructeurs/affectation par déplacement.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Et peut-être aussi inclure directement l'idiome copy-and-swap à la forme canonique.
    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.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Citation Envoyé par Ehonn Voir le message
    Et ici, la classe Point a probablement des types primitifs (comme int) en donnée membre (probablement x et y) et donc le constructeur par défaut généré par le compilateur ne fait pas la bonne chose pour moi car il ne va pas initialiser à 0 ces attributs.
    Justement, la norme précise que ce sera effectivement le cas, mais, ce qui se passe, c'est que les classes ayant sémantique de valeur devraient surtout avoir le bon gout d'être immuables, à moins que cet état ne provoque de fortes pertes de performances (ex : la class string qui est muable, à cause des allocation dynamiques et des nombreuses copies que représenteraient le fait qu'elle soit immuable).

    Ta classe Point pourrait parfaitement être immuable, mais la conséquence est que tu serait alors obligé de fournir un constructeur acceptant les deux valeurs devant être utilisées pour l'abscisse et l'ordonnée, et, partant, que tu donnerais une bonne raison au compilateur de ne pas implémenter le constructeur par défaut pour cette classe.

    Du coup, si tu veux profiter du constructeur par défaut (chose sans doute indispensable, si tu envisage à un moment donné de créer un tableau de Point, par exemple), tu devras donc en implémenter un par toi même
    Citation Envoyé par Flob90 Voir le message
    @koala01: Un peu dépassé la forme canonique a 4 éléments. Tu pourrais inclure les constructeurs/affectation par déplacement.
    Euhh, oui, en effet, si on se base sur les possibilités de C++11... Mais non, pas tant que jim n'aura pas revu sa forme pour l'adapter aux nouvelles possibilités

    Disons plutôt que, la norme C++11 ayant prévu la possibilité de déplacer les objets en mémoire, elle a eu le bon gout de se dire qu'il y avait des constructeur de copie et opérateur d'affectation susceptible de provoquer ce déplacement et que ces nouvelles fonctions devraient suivre les règles indiquées par jim pour leurs homologues sans déplacement. Cela ne change malgré tout rien à la forme de Coplien (par contre, la notion de déplacement a un impact direct sur la règle des trois grands )
    Citation Envoyé par Médinoc Voir le message
    Et peut-être aussi inclure directement l'idiome copy-and-swap à la forme canonique.
    Pas si la copie et / ou l'affectation ne risque pas de provoquer d'exception...
    L'idiome copy-and-swap a en réalité deux buts distincts:
    • S'assurer qu'il n'y aura pas de fuites mémoire si on utilise des ressources pour lesquelles on a eu recours à l'allocation dynamique de la mémoire
    • S'assurer qu'un objet ne soit pas modifié si le processus d'affectation venait à provoquer une exception, respectant d'une certaine manière le principe ACID des bases de données (et provoquant un "roll back" si une action vient à échouer )
    Dans l'exemple de la classe Point ou Segment, l'idiome copy-and-swap n'a aucun intérêt
    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. [Débutant] Classe, Constructeur et objet, une question toute bête
    Par OurPleasure dans le forum C#
    Réponses: 14
    Dernier message: 14/01/2015, 15h11
  2. Constructeur et objet
    Par odysseeh dans le forum Débuter
    Réponses: 7
    Dernier message: 27/04/2013, 11h43
  3. Réponses: 3
    Dernier message: 23/01/2012, 17h34
  4. Constructeur d'objet null
    Par tchoimars dans le forum Windows Forms
    Réponses: 4
    Dernier message: 09/02/2009, 17h47
  5. algorithme constructeur en objet
    Par sicilianadev dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 31/10/2008, 15h10

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