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 :

std::map et constructeur à appeler


Sujet :

C++

  1. #1
    Membre habitué
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mai 2014
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 227
    Points : 162
    Points
    162
    Par défaut std::map et constructeur à appeler
    Bonjour à tous, je suis en train de réorganiser mon code et pour garder les boutons de mes menus en mémoire, j'ai choisi de créer une map. Quand je compile mon code il essaye d'utiliser le constructeur par défaut de ma class bouton, je ne sais pas si l'erreur vient de ma conception ou s'il faut bel et bien "préciser" le constructeur à utilisé ? enfin bref je suis un peu perdu...
    Quelqu'un a une solution ?

    Code de la déclaration :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::map<std::string, Button> menu;
    Code qui remplie la map d'un bouton :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    menu["play"] = Button(sf::Vector2f( 0, 0 ), sf::Vector2f( 700, 400 ), s);
    Class du bouton :
    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
     
    #ifndef Button_included
    #define Button_included
     
    #include <SFML/Graphics.hpp>
     
    class Button : public sf::Drawable, public sf::Transformable /// inlining !
    {
    public:
     
        Button( sf::Vector2f const &position, sf::Vector2f const &size, std::string const &text );
        Button( sf::Vector2f const &position, sf::Vector2f const &size, sf::Sprite const &sprite );// à créer en interne
        bool isTouch( sf::Vector2f const &mousePosition ) const;
     
    private:
     
        sf::Vector2f button_position;
        sf::Vector2f button_size;
        sf::Sprite button_sprite;
        std::string button_text;
     
        virtual void draw( sf::RenderTarget& target, sf::RenderStates states ) const; /// s'occuper de la version textuelle
     
    };
     
    #endif // Button_included
    Erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    no matching function for call to 'Button::Button()'|
    Merci

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 130
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 130
    Points : 33 063
    Points
    33 063
    Billets dans le blog
    4
    Par défaut
    Parce que l'opérateur[] d'une map crée un objet s'il n'existe pas. Et sa seule possibilité c'est d'appeler le constructeur par défaut du type valeur.

  3. #3
    Membre habitué
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mai 2014
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 227
    Points : 162
    Points
    162
    Par défaut
    Oui ça j'ai compris, donc comment je résout mon problème ?

  4. #4
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 492
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 492
    Points : 6 202
    Points
    6 202
    Par défaut
    Réponse courte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    // Insérer un élément :
    menu.insert(std::make_pair(std::string("play"),
                               Button(sf::Vector2f( 0, 0 ), sf::Vector2f( 700, 400 ), s)));
     
    // Accéder à un élément :
    Button& button = menu.at("play");
    Quelques compléments, plus compliqués :

    Quelques précisions sur la ligne de code avec insert :
    • Dans un premier temps, on a deux objets temporaires : std::string("play") et Button(sf::Vector2f( 0, 0 ), sf::Vector2f( 700, 400 ), s).
    • A partir d'eux, on crée un 3e objet temporaire de type std::pair<std::string, Button>.
      Le constructeur de mouvement de std::string est appelé : La chaîne de caractères "play" n'est pas copiée mais déplacée de l'objet temporaire std::string("play") vers l'objet temporaire de type std::pair<std::string, Button>.
      Le constructeur de mouvement de Button est appelé aussi, si ce dernier est public. Sinon, c'est le constructeur de copie de Button qui est appelé.
    • Ensuite, la fonction insert récupère cet objet temporaire std::pair<std::string, Button> et sauvegarde dans l'arbre un objet du même type (std::pair<std::string, Button>). Comme tout à l'heure, le constructeur de mouvement de std::string est appelé. Le constructeur de mouvement de Button est appelé aussi, si ce dernier est public. Sinon, c'est le constructeur de copie de Button qui est appelé.


    Illustration :
    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
    class Foo
    {
    private:
        int m_entier;
        Foo(const Foo& other)    : m_entier(other.m_entier) {std::cout << "copy ctor\n";}
        Foo& operator=(const Foo& other) {m_entier = other.m_entier; return *this;}
        Foo& operator=(Foo&& other)      {m_entier = other.m_entier; return *this;}
    public:
        explicit Foo(int entier) : m_entier(m_entier)       {}
        Foo(Foo&& other)         : m_entier(other.m_entier) {std::cout << "move ctor\n";}
    };
     
    int _tmain(int argc, _TCHAR* argv[])
    {
        std::map<std::string, Foo> fooMap;
        fooMap.insert(std::make_pair(std::string("deux"), Foo(2))); // deux appels au move ctor de Foo
        Foo& cool = fooMap.at("deux");
    //  fooMap["deux"] = Foo(2);       // erreur de compilation car Foo n'a pas de constructeur par défaut et l'affectation est privée
    //  Foo& pasCool = fooMap["deux"]; // erreur de compilation car Foo n'a pas de constructeur par défaut
        return 0;
    }
    Remarque : Le constructeur de mouvement Button::Button(Button&& other) n'est pas explicitement évoqué dans ta classe, donc ton programme va peut-être en générer un quand même, silencieusement, avec une visibilité publique. Du moins, il le fera si tes classes sf::Vector2f et sf::Sprite ont un constructeur de mouvement public (généré automatiquement ou défini explicitement). Alors, le constructeur de mouvement généré appellera le constructeur de mouvement de chaque membre de la classe.
    Même remarque pour le constructeur de copie Button::Button(const Button& other).

  5. #5
    Membre habitué
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mai 2014
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 227
    Points : 162
    Points
    162
    Par défaut
    Ça y est, tout est bon ! Je te remercie

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

Discussions similaires

  1. grandes std::map, constructeur?
    Par regisportalez dans le forum SL & STL
    Réponses: 10
    Dernier message: 06/04/2010, 17h09
  2. Accession aux std::map triées ?
    Par Matthieu Brucher dans le forum SL & STL
    Réponses: 5
    Dernier message: 18/11/2005, 15h44
  3. std::map<int,CStringArray> ????
    Par philippe V dans le forum MFC
    Réponses: 1
    Dernier message: 12/10/2005, 07h48
  4. Libérer des pointeurs dans une std::map
    Par GaldorSP dans le forum SL & STL
    Réponses: 2
    Dernier message: 09/07/2005, 15h42
  5. Trier un std::map selon les valeurs plutot que les clés
    Par dj.motte dans le forum SL & STL
    Réponses: 2
    Dernier message: 13/11/2004, 22h54

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