Précédent   Forum du club des développeurs et IT Pro > C et C++ > C++ > Langage
Langage Langage C++, Programmation Orientée Objet, Templates, etc. Avant de poster : FAQ C++
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 25/02/2013, 15h04   #1
Negatio
Invité de passage
 
Homme
Inscription : 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.
Negatio est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2013, 15h37   #2
leternel
Expert Confirmé
 
Homme Pierre
Ingénieur développement logiciels
Inscription : juin 2007
Messages : 1 185
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 : 1 185
Points : 2 502
Points : 2 502
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.
leternel est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2013, 15h47   #3
Médinoc
Expert Confirmé Sénior
 
Avatar de Médinoc
 
Homme
Développeur informatique
Inscription : septembre 2005
Messages : 22 384
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France

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

Informations forums :
Inscription : septembre 2005
Messages : 22 384
Points : 32 024
Points : 32 024
Envoyer un message via MSN à Médinoc
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.
Médinoc est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2013, 15h59   #4
Negatio
Invité de passage
 
Homme
Inscription : 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
D'abord merci pour une réponse si rapide.

Citation:
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".

Citation:
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".
Negatio est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2013, 16h11   #5
leternel
Expert Confirmé
 
Homme Pierre
Ingénieur développement logiciels
Inscription : juin 2007
Messages : 1 185
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 : 1 185
Points : 2 502
Points : 2 502
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.
leternel est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2013, 16h15   #6
Negatio
Invité de passage
 
Homme
Inscription : 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
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.
Negatio est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2013, 16h18   #7
Médinoc
Expert Confirmé Sénior
 
Avatar de Médinoc
 
Homme
Développeur informatique
Inscription : septembre 2005
Messages : 22 384
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France

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

Informations forums :
Inscription : septembre 2005
Messages : 22 384
Points : 32 024
Points : 32 024
Envoyer un message via MSN à Médinoc
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.
Médinoc est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 11h44.


 
 
 
 
Partenaires

Hébergement Web