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 attributs d'une classe qui sont instances d'une autre classe


Sujet :

C++

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    etudiant
    Inscrit en
    Novembre 2021
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

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

    Informations forums :
    Inscription : Novembre 2021
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Constructeur et attributs d'une classe qui sont instances d'une autre classe
    Bonjour,
    Je suis entrain d'apprendre le C++ orienté objet avec le MOOC de coursera.
    Je suis entrain de bloquer sur un concept en particulier, celui qui consiste a avoir dans une classe un attribut qui est une instance d'une autre classe.
    Je voudrais connaitre tout d'abord le terme exacte de cette pratique en programmation.

    Ensuite je voudrais savoir dans le code ci dessous, quand exactement mes constructeurs sont appeles, a quelle niveau de mon code ? Est ce au niveau de la declaration d'une instance comme
    quand je marque : "Article choufleur ("Chou-fleur extra" , 3.50 );" pour les instances de la classe Article ?
    Mais alors quand je marque : "Achat achat1(choufleur, 2);" comment cela se passe t'il ? ici je declare un objet "achat1" qui contient une instance "choufleur" de la classe "Article".

    Sinon je comprends bien le principe d'avoir acces au methode d'une classe par le biais d'une instance d'une autre classe, par exemple quand je marque : "cout << achat1.price() << endl;" car l'attribut "article_" est de type Article donc j'ai bien acces aux methodes de "Article".
    Mais je me perds vraiment dans les histoires de constructeurs quand une classe a des attributs qui sont une instance d'une autre classe.

    Merci infiniment d'avance pour vos reponses



    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
    #include <iostream>
    #include <vector>
    #include <string>
    using namespace std;
    // ======================================================================
    class Article {
    public:
    Article(string const& nom, double prix, bool action = false)
    : nom_(nom), prix_(prix), action_(action)
    {}
    double prix() const { return prix_; }
    string nom() const { return nom_; }
    bool est_en_action() const { return action_; }
    private:
    const string nom_ ;
    double prix_ ;
    bool action_ ;
    };
    // ======================================================================
    class Achat {
    public:
    Achat(Article const& article, unsigned int quantite = 1)         //L'objet "choufleur" a été initialisé préalablement (par "Article choufleur ("Chou-fleur extra" , 3.50 ;" dans le main)
    : article_(article), quantite_(quantite)                                 //et est donc envoyé en argument avec "Article const& article"
    {}
    double price() const {
    double price_( quantite_ * article_.prix() );
    if (article_.est_en_action()) {
    price_ *= 0.5;
    }
    return price_;
    }
    void afficher() const {
    cout << article_.nom() << " : "                         //On peut utiliser la méthode "nom" car "article_" est de type "Article" donc on peut accéder aux méthodes de la classe "Article"
    << article_.prix() << " x " << quantite_
    << " = " << price() << " F";
    if (article_.est_en_action()) {
    cout << " (en action)";
    }
    cout << endl;
    }
    private:
    const Article article_;
    const unsigned int quantite_;
    };
     
    // ======================================================================
    int main()
    {
    // Les articles vendus dans le supermarché
    Article choufleur ("Chou-fleur extra" , 3.50 );                        //On appelle le constructeur de "choufleur" donc le constructeur "Article"
    Article roman ("Les malheurs de Sophie", 16.50, true );
    Article camembert ("Cremeux 100%MG" , 5.80 );
    Article cdrom ("C++ en trois jours" , 48.50 );
    Article boisson ("Petit-lait" , 2.50, true);
    Article petitspois("Pois surgeles" , 4.35 );
    Article poisson ("Sardines" , 6.50 );
    Article biscuits ("Cookies de grand-mere" , 3.20 );
    Article poires ("Poires Williams" , 4.80 );
    Article cafe ("100% Arabica" , 6.90, true);
    Article pain ("Pain d'epautre" , 6.90 );
     
    cout<< choufleur.nom() << endl;
    cout<< choufleur.prix() << endl;
    cout<< choufleur.est_en_action() << endl;
    cout<< endl;
     
    Achat achat1(choufleur, 2);                             //On appelle le constructeur de "achat1" donc le constructeur "Achat", notez que "choufleur" a déjÃ* été initialisé précédemment
    Achat achat2(cdrom );
    Achat achat3(biscuits , 4);
    Achat achat4(boisson , 6);
    Achat achat5(poisson , 2);
     
    cout << achat1.price() << endl;
    cout << achat2.price() << endl;
     
    achat1.afficher();
    achat2.afficher();
     
    return 0;
    }

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 631
    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 631
    Points : 10 558
    Points
    10 558
    Par défaut
    Pour te donner des pistes

    on dit agrégation et composition en UML. La différence, c'est la vie de l'objet B : soit A le construit et/ ou le détruit, soit B est déjà construit.

    Ce n'est pas 1 instance, c'est juste 1 objet const Article article_;: en UML, c'est juste 1 association.
    En C++, 1 instance est soit 1 pointeur soit 1 référence.

    Sinon dans ton constructeur Achat(Article const& article, unsigned int quantite = 1) : article_(article), quantite_(quantite) tu appelles 1 constructeur par recopie Article(const Article&) que tu n'as pas défini.

  3. #3
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 118
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 118
    Points : 1 644
    Points
    1 644
    Par défaut
    Salut,

    Quelques commentaires sur ton code:
    1) Retire cette horrible directive "using namespace std".
    Cette dernière n'a pour seul but que d'assurer la compatibilité des anciens codes avec la librairie standard, et n' aucun raison d'être présente dans du code moderne.

    2) Lors de l'initialisation de membres d'une classe, on préfère utiliser des accolades.
    D'une part, ca évite les confusions (Initialisation ? Appel d'une fonction ? Appel d'un constructeur paramétré ou de recopie ?).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Foo
    {
    private:
        std::string Data;
    public:
        Foo():
            Data{ "Something" }
        {}
    };
    3) Pose toi la question de la sémantique de tes classes, entité ou valeur.
    Dans le cas des classes à sémantique d'entité, assigner ou recopier cette dernière n'a pas de sens, on veillera à supprimer le constructeur de recopie et l'opérateur d'assignation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Foo
    {
    public:
        Foo(Foo const&) = delete;
        Foo& Operator=(Foo const&) = delete;
    };
    5) On préfère éviter les noms avec un underscore à la fin, ce n'est pas super lisible.
    Beaucoup de programmeur préfixent les variables membre par la lettre m (comme member).
    Tu peux très bien leur donner le même nom que les paramètres, dans ce cas il te faudra lever les ambiguïtés via le pointeur this.

    Pour répondre à ta question:
    Lors de l'instanciation d'une classe (la ligne où une variable du type de la classe est déclarée), le constructeur de cette dernière est appelé.
    Ce dernier commence par initialiser les membres de la classe, si nécessaire les constructeurs de classes contenues sont appelés (et le même processus se répète).
    Un bon moyen de s'en rendre compte, est via le debugger de ton IDE favoris et d'exécuter en pas à pas.
    Dans une moindre mesure, tu peux mettre des affichages dans les constructeurs de tes classes.

  4. #4
    Nouveau Candidat au Club
    Homme Profil pro
    etudiant
    Inscrit en
    Novembre 2021
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

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

    Informations forums :
    Inscription : Novembre 2021
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Merci beaucoup pour les conseils et renseignements

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

Discussions similaires

  1. [Python 3.X] POO : méthode de classe imbriquée modifiant attribut d'une autre classe imbriquée.
    Par In.Abysso dans le forum Général Python
    Réponses: 7
    Dernier message: 26/07/2016, 10h46
  2. Accès aux attributs d'une autre classe
    Par alexmam15 dans le forum Débuter
    Réponses: 5
    Dernier message: 25/02/2011, 09h26
  3. Réponses: 3
    Dernier message: 23/05/2009, 18h57
  4. Modifier un attribut représentant une autre classe
    Par piotrr dans le forum Hibernate
    Réponses: 6
    Dernier message: 13/05/2008, 11h58
  5. Réponses: 0
    Dernier message: 23/04/2008, 10h25

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