Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 7 sur 7
  1. #1
    Invité de passage
    Homme Profil pro
    Inscrit en
    décembre 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : décembre 2012
    Messages : 15
    Points : 1
    Points
    1

    Par défaut error: request for member 'x' in 'y', which is of non-class type

    Bonjour/bonsoir,

    Je nécessite votre aide a propos d'un problème sur lequel je m'arrache les cheveux depuis prés de 4 heures.

    J'ai créer une classe GameScreen et une classe GuiScreen. Ma classe GameScreen contient un objet de type GuiScreen.

    GameScreen.h
    Code :
    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
    #ifndef DEF_GAMESCREEN
    #define DEF_GAMESCREEN
     
    #include "Engine.h"
    #include "EngineRender.h"
    #include "Gui.h"
    #include "GuiScreen.h"
    #include "GuiTest.h"
     
    using namespace std;
    using namespace sf;
     
    class GameScreen
    {
        public:
     
        GameScreen(GuiScreen& guiScreen);
        ~GameScreen();
        GuiScreen GetGuiScreen();
        void Draw();
        void Update();
     
        protected:
     
        GuiScreen m_guiScreen;
    };
     
    #endif
    GameScreen.cpp
    Code :
    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
    #include "GameScreen.h"
     
    GameScreen::GameScreen(GuiScreen& guiScreen)
    {
        m_guiScreen = guiScreen;
    }
     
    GameScreen::~GameScreen()
    {
     
    }
     
    GuiScreen GameScreen::GetGuiScreen()
    {
        return m_guiScreen;
    }
     
    void GameScreen::Draw()
    {
        Engine::engineRender.drawGuiScreen(m_guiScreen);
    }
     
    void GameScreen::Update()
    {
        m_guiScreen.Update();
    }
    GuiScreen.h
    Code :
    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
    #ifndef DEF_GUISCREEN
    #define DEF_GUISCREEN
    #include <vector>
    #include "Gui.h"
     
    class GuiScreen : public Gui
    {
        protected:
     
        std::vector<Gui*> m_guiList;
     
        public:
     
        GuiScreen();
        GuiScreen(int x, int y, int height, int width);
        GuiScreen(const GuiScreen& guiScreen);
        GuiScreen& operator=(GuiScreen const& guiScreen);
        ~GuiScreen();
        virtual void Update();
     
        void addGui(Gui* gui);
     
        int getGuiListSize();
        Gui* getGui(int index);
    };
     
    #endif
    GuiScreen.cpp
    Code :
    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
    #include "guiscreen.h"
     
    using namespace std;
    using namespace sf;
     
    GuiScreen::GuiScreen() :
    m_guiList(0)
    {
     
    }
     
    GuiScreen::GuiScreen(const GuiScreen& guiScreen) :
    Gui(guiScreen.m_rect.top, guiScreen.m_rect.left, guiScreen.m_rect.width, guiScreen.m_rect.height)
    {
        for(int i; i < guiScreen.m_guiList.size(); i++)
        {
           addGui(new Gui(*(guiScreen.m_guiList[i])));
        }
    }
     
     
    GuiScreen::GuiScreen(int x, int y, int height, int width):
    Gui(x, y, height, width),
    m_guiList(0)
    {
     
    }
     
    GuiScreen& GuiScreen::operator=(GuiScreen const& guiScreen)
    {
        if(this != &guiScreen)
        {
            for(int i = 0; i < guiScreen.m_guiList.size(); i++)
            {
                addGui(new Gui(*(guiScreen.m_guiList[i])));
            }
        }
        return *this;
    }
     
    GuiScreen::~GuiScreen()
    {
        for(int i(0); i<m_guiList.size(); ++i)
        {
            delete m_guiList[i];
        }
    }
     
    void GuiScreen::Update()
    {
     
    }
     
    void GuiScreen::addGui(Gui* gui)
    {
       m_guiList.push_back(gui);
    }
     
    int GuiScreen::getGuiListSize()
    {
        return m_guiList.size();
    }
     
     
    Gui* GuiScreen::getGui(int index)
    {
        return m_guiList[index];
    }
    J'ai aussi créer une classe GuiTest qui hérite de GuiScreen qui ne fait que ajouter des éléments dans le tableau "m_guiList"

    main.c
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #include <iostream>
    #include <SFML/Graphics.hpp>
    #include <SFML/Window.hpp>
    #include <SFML/OpenGL.hpp>
     
    #include "Engine.h"
    #include "EngineWindow.h"
    #include "EngineControl.h"
    #include "EngineSystem.h"
    #include "EngineRender.h"
    #include "GuiScreen.h"
    #include "GameScreen.h"
     
    using namespace std;
    using namespace sf;
     
    int main()
    {
        GameScreen testScreen(GuiTest());
        testScreen.Draw();
     
        return 0;
    }
    Avec tout ce foutoir j'obtient l'erreur suivante:
    error: request for member 'Draw' in 'testScreen', which is of non-class type 'GameScreen(GuiTest (*)())'

    Je débute avec les constructeur de copie et les operateur d'affectation donc l'erreur vient peut-être de là. J'ai fait quelque recherche sur ce message d'erreur et j'ai vu que la plupart du temps c’était des gens qui se trompais en déclarant une fonction a la place d'utiliser le constructeur par défaut (en faisant "Classe objet()" au lieu de "Classe objet") mais je ne pense pas que ce soit mon cas.

    Merci d'avoir lu mon pavé, en espérant que mes nombreuses, éventuelles fautes d'orthographe n'auront pas réussi a vous décourager a me répondre.

  2. #2
    Expert Confirmé Sénior

    Homme Profil pro Pierre
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    2 182
    Détails du profil
    Informations personnelles :
    Nom : Homme Pierre
    Localisation : France

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

    Informations forums :
    Inscription : juin 2007
    Messages : 2 182
    Points : 5 057
    Points
    5 057

    Par défaut

    D'abord, pour un constructeur, il faut toujours privilégier les initialiseurs.
    Ensuite, une référence devrait être constante autant que possible.
    Enfin, la copie se fait sur un objet de meme type.

    En l'occurence, le constructeur de GameScreen devrait être:
    Code :
    GameScreen::GameScreen(const GuiScreen& guiScreen) :m_guiScreen(guiScreen){}
    Par ailleurs, ceci GameScreen testScreen(GuiTest()); déclare testScreen comme une fonction prenant une fonction retournant un GuiTest et retournant un GameScreen.

    Ceci est du aux relations dangereuses entre valeurs temporaires et référence non constantes.
    pour résoudre ton probleme sans changer le constructeur, procede par étape:
    Code :
    1
    2
    3
    4
    5
    6
    7
     
    int main() {
        GuiTest guiTest;
        GameScreen testScreen(guiTest);
        //…
        return 0;
    }
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • La plus sotte des questions est celle qu'on ne pose pas.

    Pour faire des graphes, essayez yEd.

  3. #3
    Expert Confirmé Sénior Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    septembre 2005
    Messages
    24 127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France

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

    Informations forums :
    Inscription : septembre 2005
    Messages : 24 127
    Points : 35 208
    Points
    35 208

    Par défaut

    Au passage, GuiScreen::operator= se comporte comme s'il s'agissait de GuiScreen::operator+=. Tu devrais utiliser l'idiome copy-and-swap à la place:

    Code C++ :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void GuiScreen::swap(GuiScreen &guiScreen)
    {
    	Gui::swap(guiScreen);
    	m_guiList.swap(guiScreen.m_guiList);
    }
     
    void GuiScreen::operator=(GuiScreen const &guiScreen)
    {
    	GuiScreen copie(guiScreen);
    	swap(copie);
    }
    Cette version est plus facile à comprendre, mais la version suivante est plus optimisée: Dans certains cas de construction, elle peut économiser une copie.
    Code C++ :
    1
    2
    3
    4
    void GuiScreen::operator=(GuiScreen copie)
    {
    	swap(copie);
    }
    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.

  4. #4
    Invité de passage
    Homme Profil pro
    Inscrit en
    décembre 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : décembre 2012
    Messages : 15
    Points : 1
    Points
    1

    Par défaut

    D'abord merci pour une réponse si rapide.

    Par ailleurs, ceci GameScreen testScreen(GuiTest()); déclare testScreen comme une fonction prenant une fonction retournant un GuiTest et retournant un GameScreen.
    Je ne savais pas qu'on pouvait mettre un fonction comme argument , et je me demande a quoi ca peut servir. Il me semble pourtant qu'on peut déclarer un objet directement dans les parenthèses, non?
    Peut-être comme ca: GameScreen testScreen(GuiTest);

    Code :
    1
    2
     GuiTest guiTest;
     GameScreen testScreen(guiTest);
    C'est ce que j'avais fait mais je trouvais un peu étrange de créer un objet juste pour le passer en argument.

    Ca fonctionne mais a la ligne 20:
    Code :
    Engine::engineRender.drawGuiScreen(m_guiScreen);
    j'ai verifier dans la fonction "Engine::engineRender.drawGuiScreen" et l'argument "m_guiScreen" ne semble contenir aucun élément dans son tableau "m_guiList".

    Tu devrais utiliser l'idiome copy-and-swap à la place.
    Je n'est jamais entendu ce mot de ma vie. Il serait peut-être temps que j'aille jeter un coup d'oeil plus approfondie sur la FAQ. En attendant je vais essayer ce fameux "idiome".

  5. #5
    Expert Confirmé Sénior

    Homme Profil pro Pierre
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    2 182
    Détails du profil
    Informations personnelles :
    Nom : Homme Pierre
    Localisation : France

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

    Informations forums :
    Inscription : juin 2007
    Messages : 2 182
    Points : 5 057
    Points
    5 057

    Par défaut

    D'une manière générale, prends le temps pour lire toute la FAQ.
    C'est une mine d'or, et savoir ce qu'on y trouve est extrêment utile.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • La plus sotte des questions est celle qu'on ne pose pas.

    Pour faire des graphes, essayez yEd.

  6. #6
    Invité de passage
    Homme Profil pro
    Inscrit en
    décembre 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : décembre 2012
    Messages : 15
    Points : 1
    Points
    1

    Par défaut

    Elle ma deja sauver la vie(surtout en ce qui concerne la POO). Mais je ne sait pas si elle contient quelconque infos sur l'idiome swap-and-copy, ou alors c'est moi qui cherche pas là ou il faut.

  7. #7
    Expert Confirmé Sénior Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    septembre 2005
    Messages
    24 127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France

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

    Informations forums :
    Inscription : septembre 2005
    Messages : 24 127
    Points : 35 208
    Points
    35 208

    Par défaut

    Si tu lis l'anglais, tu peux le trouver ici: More C++ Idioms/Copy-and-swap
    Ce qui est important, c'est que le contenu du swap() ne puisse jamais lancer d'exception (Idiome Non-throwing swap) : Dedans on ne fait que permuter des pointeurs nus, des entiers, ou appeler les fonctions membres swap() des classes contenues (qui respectent les mêmes contraintes).
    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.

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

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •