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

Langage C++ Discussion :

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


Sujet :

Langage C++

  1. #1
    Futur Membre du Club
    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 : 6
    Points
    6
    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 : 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
    #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 : 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
    #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 : 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
    #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 : 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
    #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 : 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
    #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 éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #3
    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 519
    Points
    41 519
    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++ : Sélectionner tout - Visualiser dans une fenêtre à part
    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++ : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Futur Membre du Club
    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 : 6
    Points
    6
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    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.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  6. #6
    Futur Membre du Club
    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 : 6
    Points
    6
    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 é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 519
    Points
    41 519
    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.

Discussions similaires

  1. Réponses: 2
    Dernier message: 17/02/2013, 20h59
  2. Réponses: 29
    Dernier message: 23/08/2010, 09h24
  3. Problème:Erreur 'which is of non-class type
    Par abzal dans le forum Débuter
    Réponses: 9
    Dernier message: 28/11/2008, 15h54
  4. Erreur 'which is of non-class type' ?
    Par jahmanzaar dans le forum Débuter
    Réponses: 7
    Dernier message: 15/10/2008, 22h53
  5. Réponses: 14
    Dernier message: 14/09/2007, 17h28

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