1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    février 2016
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 16
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : février 2016
    Messages : 14
    Points : 6
    Points
    6

    Par défaut Problème avec les classes et les pointeurs

    Bonjour, je suis en train de réécrire un programme réalisé il y a quelques jours pour qu'il soit plus performant, j'ai donc voulu utiliser les pointeurs mais quelques problèmes sont arrivés

    Dans Player.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class Player
    {
    	public:
    		void Init();
    		void Update(int VelocityX, int VelocityY);
    		int PlayerPosX, PlayerPosY;
    };
    Dans Player.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
     
    #include "Player.h"
     
    void Player::Init()
    {
    	PlayerPosX = 0;
    	PlayerPosY = 0;
    }
     
    void Player::Update(int VelocityX, int VelocityY)
    {
    	PlayerPosX += VelocityX;
    	PlayerPosY += VelocityY;
    }
    Dans EventsManager.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #include <SFML\Graphics.hpp>
    #include "Player.h"
    class EventsManager
    {
    public:
    	void Input(sf::Event Event, sf::RenderWindow *window, Player *Player);
    };
    Dans EventsManager.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #include "EventsManager.h"
     
    void EventsManager::Input(sf::Event Event, sf::RenderWindow *window, Player *Player)
    {
    	if (Event.type == sf::Event::Closed)
    		window->close();
    	else if (Event.type == sf::Keyboard::isKeyPressed(sf::Keyboard::S))
    		Player->PlayerPosX += 5;
    }
    Dans Application/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
     
    #include <SFML\Graphics.hpp>
    #include "Player.h"
    #include "EventsManager.h"
    #include <iostream>
     
    class Application
    {
    	public:
    		void Init();
    		void Run();
    		void Update();
     
    	private:
    		int Win_WIDTH, Win_HEIGHT;
    		sf::RenderWindow GameWindow;
    		sf::Event GameEvent;
    		EventsManager GameEvents;
    		Player GamePlayer;
    };
    Dans Application.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 "Application.h"
     
    void Application::Init()
    {
    	//Create the window
    	Win_WIDTH = 1920;
    	Win_HEIGHT = 1080;
    	GameWindow.create(sf::VideoMode(Win_WIDTH, Win_HEIGHT), "TwoDCraft!", sf::Style::Default);
    	GameWindow.setFramerateLimit(60);
    	GameWindow.setPosition(sf::Vector2i(0, 0));	
     
    	//Init the player
    	GamePlayer.Init();
    }
     
    void Application::Run()
    {
    	while (GameWindow.isOpen())
    	{
    		while (GameWindow.pollEvent(GameEvent))
    		{
    			GameEvents.Input(GameEvent, &GameWindow, &GamePlayer);
    		}
    	}
    }
    Et dans le main
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #include "Application.h"
     
    int main()
    {
    	Application App;
    	App.Init();
    	App.Run();
    	return 0;
    }
    Le programme utilise SFML, peut être aurai je dût placer cette discussion dans les bibilothèques mais le problème ne concerne pas SFML. Voici mon problème : La méthode Input de EventsManager n'arrive pas à accéder et à modifier PlayerPosX
    Voici le log :
    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
     
    1>------ Début de la génération*: Projet*: TwoDCraftReWork, Configuration*: Debug Win32 ------
    1>  main.cpp
    1>f:\documents\programmation\visual studio 2015\projects\twodcraftrework\twodcraftrework\player.h(2): error C2011: 'Player'*: redéfinition du type 'class'
    1>  f:\documents\programmation\visual studio 2015\projects\twodcraftrework\twodcraftrework\player.h(2): note: voir la déclaration de 'Player'
    1>f:\documents\programmation\visual studio 2015\projects\twodcraftrework\twodcraftrework\application.h(20): error C2079: 'Application::GamePlayer' utilise une class de 'Player' non défini
    1>  EventsManager.cpp
    1>f:\documents\programmation\visual studio 2015\projects\twodcraftrework\twodcraftrework\eventsmanager.cpp(7): warning C4805: '=='*: mélange risqué de type 'sf::Event::EventType' et de type 'bool' dans l'opération
    1>  Application.cpp
    1>f:\documents\programmation\visual studio 2015\projects\twodcraftrework\twodcraftrework\player.h(2): error C2011: 'Player'*: redéfinition du type 'class'
    1>  f:\documents\programmation\visual studio 2015\projects\twodcraftrework\twodcraftrework\player.h(2): note: voir la déclaration de 'Player'
    1>f:\documents\programmation\visual studio 2015\projects\twodcraftrework\twodcraftrework\application.h(20): error C2079: 'Application::GamePlayer' utilise une class de 'Player' non défini
    1>f:\documents\programmation\visual studio 2015\projects\twodcraftrework\twodcraftrework\application.cpp(13): error C2228: la partie gauche de '.Init' doit avoir un class/struct/union
    1>  f:\documents\programmation\visual studio 2015\projects\twodcraftrework\twodcraftrework\application.cpp(13): note: le type est 'int'
    1>f:\documents\programmation\visual studio 2015\projects\twodcraftrework\twodcraftrework\application.cpp(16): error C2228: la partie gauche de '.PlayerPosX' doit avoir un class/struct/union
    1>  f:\documents\programmation\visual studio 2015\projects\twodcraftrework\twodcraftrework\application.cpp(16): note: le type est 'int'
    1>f:\documents\programmation\visual studio 2015\projects\twodcraftrework\twodcraftrework\application.cpp(16): error C2228: la partie gauche de '.PlayerPosY' doit avoir un class/struct/union
    1>  f:\documents\programmation\visual studio 2015\projects\twodcraftrework\twodcraftrework\application.cpp(16): note: le type est 'int'
    1>f:\documents\programmation\visual studio 2015\projects\twodcraftrework\twodcraftrework\application.cpp(25): error C2664: 'void EventsManager::Input(sf::Event,sf::RenderWindow *,Player *)'*: impossible de convertir l'argument 3 de 'int *' en 'Player *'
    1>  f:\documents\programmation\visual studio 2015\projects\twodcraftrework\twodcraftrework\application.cpp(25): note: Les types pointés n'ont aucun rapport entre eux*; conversion nécessitant reinterpret_cast, cast de style C ou cast de style fonction
    1>f:\documents\programmation\visual studio 2015\projects\twodcraftrework\twodcraftrework\application.cpp(35): error C2228: la partie gauche de '.PlayerPosX' doit avoir un class/struct/union
    1>  f:\documents\programmation\visual studio 2015\projects\twodcraftrework\twodcraftrework\application.cpp(35): note: le type est 'int'
    1>f:\documents\programmation\visual studio 2015\projects\twodcraftrework\twodcraftrework\application.cpp(35): error C2228: la partie gauche de '.PlayerPosY' doit avoir un class/struct/union
    1>  f:\documents\programmation\visual studio 2015\projects\twodcraftrework\twodcraftrework\application.cpp(35): note: le type est 'int'
    1>  Génération de code en cours...
    ========== Génération*: 0 a réussi, 1 a échoué, 0 mis à jour, 0 a été ignoré ==========
    J'espère que vous aurez compris mon problème et je vous remercie d'avance de votre aide
    Bonne journée

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    4 810
    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 : 4 810
    Points : 15 632
    Points
    15 632

    Par défaut

    En C++, il existe une règle dite ODR (One Definition Rule), qui se résume à chaque chose doit être définie une seule fois.

    Cela vaut aussi pour les définitions de types, comme les classes, avec une légère subtilité: un type peut être défini dans deux unités de compilations distinctes s'il est défini à l'identique (cela permet d'avoir des en-têtes).
    On ne doit jamais avoir deux définitions d'un même type, même identiques, dans la même unité, c'est à dire, un .cpp et tout ce qu'il inclue, récursivement.

    Il arrive qu'un même fichier.h soit inclus plusieurs fois, parce qu'un fichier qu'on inclue l'inclue lui aussi.
    Lorsque le mot "redéfinition" apparait dans une erreur de compilation, surtout dans un en-tête, c'est à coup sûr que tu as oublié de mettre les "gardes de double inclusion" (double include guard)

    Dans ton cas, EventsManager.h inclue Player.h.
    Du coup, quand application.h inclue successivement Player.h puis EventsManager.h, il contient deux fois le contenu de Player.h.

    L'idée, c'est que chaque fichier.h se présente ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #ifndef UN_NOM_ASSEZ_UNIQUE_POUR_CE_FICHIER
    #define UN_NOM_ASSEZ_UNIQUE_POUR_CE_FICHIER
     
    // le contenu normal du fichier
     
    #endif
    Ainsi, à la première inclusion, le UN_NOM_ASSEZ_UNIQUE_POUR_CE_FICHIER n'est pas défini, donc il le devient et le contenu est inclus, et à la seconde, rien n'est inclus.

    Une fois cela réglé, tu pourras regarder de plus près tes pointeurs.
    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
    Membre expérimenté
    Avatar de Daïmanu
    Homme Profil pro
    Étudiant
    Inscrit en
    janvier 2011
    Messages
    474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : janvier 2011
    Messages : 474
    Points : 1 638
    Points
    1 638

    Par défaut

    Bonjour.

    Le premier message d'erreur t'indique que Player *Player n'est pas correct, la variable et le type on exactement le même nom, pareil pour Event.

    De manière générale il faut choisir une convention de nommage de variables cohérentes pour éviter ce soucis.
    Je fais appel aux esprits de Ritchie, Kernighan, Stroustrup et Alexandrescu
    Donnez moi la force, donnez moi le courage de coder proprement !

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    février 2016
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 16
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : février 2016
    Messages : 14
    Points : 6
    Points
    6

    Par défaut

    Merci beaucoup pour votre aide !
    Ternel, donc le fait de rajouter à la définition de chaque en tête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #ifndef UN_NOM_ASSEZ_UNIQUE_POUR_CE_FICHIER
    #define UN_NOM_ASSEZ_UNIQUE_POUR_CE_FICHIER
     
    // le contenu normal du fichier
     
    #endif
    corrige l'erreur, en fait #ifndef PLAYER est une condition qui si PLAYER n'est pas pas definit il le définit alors par la classe Player mais je ne vois pas l'utilité du nom qui suit #ifndef et #define.

    Et en effet Daïmanu il y a des confusions entre les noms des varaibles et leurs types, je corrige ça tout de suite

  5. #5
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    4 810
    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 : 4 810
    Points : 15 632
    Points
    15 632

    Par défaut

    #ifndef PLAYER est une commande du préprocesseur, équivalente à #if ! defined(PLAYER), qui vérifie si PLAYER n'est pas une macro définie.
    Si elle n'est pas définie, tout ce qui suit (jusqu'au #endif correspondant) est compilé, sinon, c'est ignoré.

    C'est le #define PLAYER qui défini cette macro (sans valeur). Tu remarqueras que c'est fait après le test.

    Dans le cas de la garde de double inclusion, je recommande une nom du genre PROJET_CHEMIN_GUARD_FICHIER_H par exemple TWODCRAFTREWORK_GUARD_PLAYER_H.

    C'est totalement indépendant (en théorie) du code que tu mets entre le #if et le #endif.

    N'hésite pas à lire une documentation de référence du langage, par exemple la page sur le préprocesseur de cppreference.com
    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
    Rédacteur/Modérateur

    Homme Profil pro
    Network game programmer
    Inscrit en
    juin 2010
    Messages
    4 404
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : juin 2010
    Messages : 4 404
    Points : 17 259
    Points
    17 259

    Par défaut

    Petite correction:
    Citation Envoyé par ternel Voir le message
    #ifndef PLAYER est une commande du préprocesseur, équivalente à #if !defined(PLAYER), qui vérifie si Bidule est une macro définie.
    Le n étant là pour not.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  7. #7
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    4 810
    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 : 4 810
    Points : 15 632
    Points
    15 632

    Par défaut

    Oups, merci, c'est corrigé
    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

  8. #8
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2011
    Messages
    479
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : juin 2011
    Messages : 479
    Points : 2 018
    Points
    2 018

    Par défaut

    Pourquoi des pointeurs sur Player et Windows et non pas des références ?

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    février 2016
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 16
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : février 2016
    Messages : 14
    Points : 6
    Points
    6

    Par défaut

    Merci pour vos réponses ! Le problème est donc résolu
    J'utilise des pointeurs et non des références car en utilisant ces dernières, je recrée une variable, je perds donc en performances (du moins d'après ce que j'ai compris sur les références)

  10. #10
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    4 810
    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 : 4 810
    Points : 15 632
    Points
    15 632

    Par défaut

    C'est justement le contraire, une référence ne crée pas de copie de la chose référencée.
    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

  11. #11
    Membre éprouvé
    Profil pro
    Inscrit en
    mai 2006
    Messages
    779
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : mai 2006
    Messages : 779
    Points : 1 162
    Points
    1 162

    Par défaut

    Par défaut on utilise pas de pointeurs en C++. La raison d'utiliser les pointeurs ce n'est pas la performance.

    Les références servent à passer l'objet en lui même sans faire de copie.

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

Discussions similaires

  1. les services métiers / les classes métiers / les classes services
    Par titititiangel dans le forum Développement Web en Java
    Réponses: 0
    Dernier message: 27/05/2013, 11h01
  2. les methodes et les associations entre les classes
    Par zin_rbt dans le forum Diagrammes de Classes
    Réponses: 1
    Dernier message: 24/05/2010, 14h41
  3. les classes et les templates dans les plugins
    Par asoka13 dans le forum C++
    Réponses: 22
    Dernier message: 24/01/2008, 17h11
  4. Problème avec les classes et les méthodes abstract
    Par BOLARD dans le forum Langage
    Réponses: 5
    Dernier message: 22/09/2007, 20h27

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