Partage
  • Partager sur Facebook
  • Partager sur Twitter

Initialiser un vector avec le constructeur d'objet

Initialiser un attribut de type vector via constructeur d'objet C++

    10 avril 2019 à 11:45:31

    Bonjour!

    Je suis en plein dans le cours c++ d'openclassrooms.

    Pour me familiariser avec la notion d'objet, je me suis décider à créer un tout petit programme utilisant les objets et les notions vues précédemment.

    Donc dans l'idée voici ce que j'aimerai faire : permettre à l'utilisateur de créer un personnage (pseudo, mdp, rôle) et ce personnage possèdera de l'expérience, un niveau et un inventaire. Toutes ces informations étant stocké dans un fichier local (librairie <fstream>). Et j'implémenterai des méthodes plutôt basique comme pouvoir afficher son inventaire, pouvoir afficher ses informations, modifier son pseudo et mdp... 

    Voilà pour ce qui est de l'idée que je me fais de mon "auto-exercice". Pour ce faire j'utiliserai un objet "User" avec des attributs et méthodes.

    Et mon problème est le suivant : Je souhaite que l'inventaire soit un tableau dynamique (pour des raisons évidente, je suppose). Mais... lors ce que j'initialise les attributs de l'objet par le constructeur, ça se passe bien pour les strings/int etc... mais venu au vector, il ne veut pas. Et je n'arrive pas à résoudre le problème.

    Voilà mes morceaux de code.
    L'en-tête contenant le prototype de ma classe
    #ifndef FONCTIONS_HPP
    #define FONCTIONS_HPP
    
    #include <iostream>
    #include <vector>
    
    class User {
        
        //Attributs of User object
        private:
            std::string a_username;
            std::string a_password;
            std::string a_type;
    
            unsigned int a_exp;
            unsigned int a_level;
    
            std::vector<std::string> a_inventory;
    
        //Methods of User object
        public:
            User(); //default constructor
            User(std::string username, std::string password, std::string type);
            void changeUsername(std::string newUsername, std::string user);
            void changePassword(std::string newPassword, std::string user);
            void displayInventory(std::string user);
            void displayInformations(std::string user);
    };
    
    #endif //FONCTIONS_HPP
    Et ici mon fichier de fonction dans lequel ma classe est explicitée.
    #include "fonctions.hpp"
    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <string>
    
    using namespace std;
    
    User::User(string username, string password, string type) :
        a_exp(0),
        a_level(1),
        a_inventory("Rusty sword")
    {/* Basic new user constructor */}
    Et l'erreur que j'obtiens : 
    Erreur	E0289	aucune instance du constructeur "std::vector<_Ty, _Alloc>::vector [avec _Ty=std::string, _Alloc=std::allocator<std::string>]" ne correspond à la liste d'argument
    
    Du coup mon erreur est signalé au niveau de : a_inventory("Rusty sword")

    Je comprends la couille, mais finalement je ne sais pas comment initialiser ce vector... j'ai essayer des trucs du genre a_inventory.push_back("blabla") mais à priori ça ne fonctionne pas...

    Voilà, désolé pour ce pavé.
    Je vous souhaite une excellente journée.
    Merci :)

    -
    Edité par Orion- 10 avril 2019 à 11:47:53

    • Partager sur Facebook
    • Partager sur Twitter
      10 avril 2019 à 12:39:31

      Salut,

      Déjà, une fonction changeUserName n'a pas vraiment de sens, ne serait-ce que parce que,

      • deux utilisateurs n'auront pas le même nom d'utilisateurs
      • parce si tu change le nom d'utilisateur, tu changes carrément d'utilisateur et
      • parce que, une fois que l'utilisateur a choisi son "pseudo" (car, c'est de cela qu'il s'agit), il n'a -- a priori - aucune raison d'en changer par la suite

      Ensuite, comme chaque utilisateur dispose de "toutes les informations" qui lui son propres -- y compris son nom d'utilisateur -- il n'y a absolument aucune raison pour que tu transmette le nom d'utilisateur aux fonction displayInvenory et displayInformaton : quand tu fais appel à ces fonctions à partir d'un utilisateur donné, c'est forcément son propre inventaire (respectivement ses propres informations) qu'il va t'afficher.

      Au passage, un constructeur par défaut n'a pas d'avantage de sens dans le cas présent, car tout utilisateur doit -- forcément -- disposer au minimum d'un nom d'utilisateur valide (et sans doute aussi d'un type valide) lorsqu'il est créé.  Le minimum requis pour le oonstructeur doit donc être de fournir ce nom d'utilsateur (et, le cas échéant, le type).

      Enfin, pour répondre à ta question, std::vector propose deux constructeurs qui pourraient convenir dans ta situaion:

      le premier nécessite de fournir comme premier paramètre le nombre d'éléments à créer et comme deuxième paramètre la valeur à donner à chaque élément.  Dans ton cas, tu pourrais l'utiliser en indiquant que tu veux créer une chaine de caractère dont la valeur serait "Rusty Sword".

      Un code proche de

      User::User(string const & username, string const & password, string const & type) :
              a_username{username},
              a_password{password},
              a_type{type},
              a_exp(0),
              a_level(1),
              a_inventory{1,"Rusty sword"}{
      }

      devrait -- a priori -- faire l'affaire ;)

      Le deuxième nécessite de fournir un itérateur (ou "tout ce qui pourrait passer comme tel" sur le premier élément et un autre itérateur sur "ce qui suit le dernier élément" que tu voudrais placer par défaut dans le tableau, mais ne sera pas vraiment simple à utiliser dans ton cas.

      -
      Edité par koala01 10 avril 2019 à 12:43:46

      • Partager sur Facebook
      • Partager sur Twitter
      Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
        10 avril 2019 à 13:07:39

        Salut koala01 !

        Tout d'abord merci pour t'a réponse. C'est concis, clair et ça me permet enfin d'avancer :)

        Effectivement, avec ce que tu me dis, je suis d'accord, la fonction "changeUsername" est plutôt inutile.

        J'ai corriger avec ce que tu m'as donné et les erreurs ont bien disparu !

        Cependant je ne suis pas sûr d'avoir vraiment compris ce passage : Au passage, un constructeur par défaut n'a pas d'avantage de sens dans le cas présent, car tout utilisateur doit -- forcément -- disposer au minimum d'un nom d'utilisateur valide (et sans doute aussi d'un type valide) lorsqu'il est créé.  Le minimum requis pour le oonstructeur doit donc être de fournir ce nom d'utilsateur (et, le cas échéant, le type).

        Dernière petite question, l'utilisation d'accolades au lieu de simple parenthèses pour initialiser un attribut est un choix ou une obligation syntaxique? 

        -
        Edité par Orion- 10 avril 2019 à 13:11:29

        • Partager sur Facebook
        • Partager sur Twitter
          10 avril 2019 à 14:58:39

          Un constructeur par défaut est le constructeur sans paramètre.

          @koaka01 de montre qu'un utilisateur doit toujours avoir un nom et qu'il faut le passer en paramètre des constructeurs.

          Comment passer le nom de l'utilisateur avec un constructeur sans paramètre ?

          => Il ne faut pas de constructeur par défaut.

          L'utilisation des accolades à la place des parenthèses rend des cas d'erreurs complexes pour les débutants beaucoup moins probables (déclaration de "variables" fonctions que les débutants prennent pour une déclaration de variable "initialisé par défaut").

          Ceci N'est Pas une déclaration/définition de User:

          User maVariable();

          Ceci EST une déclaration/définition de User:

          User maVariable{};

          • Partager sur Facebook
          • Partager sur Twitter
          Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.

          Initialiser un vector avec le constructeur d'objet

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown