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 :

Problème avec les classes et les pointeurs


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 39
    Points : 31
    Points
    31
    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
    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
    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 émérite
    Avatar de Daïmanu
    Homme Profil pro
    Développeur touche à tout
    Inscrit en
    Janvier 2011
    Messages
    696
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur touche à tout

    Informations forums :
    Inscription : Janvier 2011
    Messages : 696
    Points : 2 439
    Points
    2 439
    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 !

    « Ça marche pas » n'est PAS une réponse convenable, merci de détailler le souci en fournissant l’environnement, le code source, les commandes et les messages d'erreur.

    Ce club possède également un clavardage, on y trouve quelques perles entre deux sessions d'entraides.

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 39
    Points : 31
    Points
    31
    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
    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
    #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
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    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
    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
    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 expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    739
    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 : 739
    Points : 3 627
    Points
    3 627
    Par défaut
    Pourquoi des pointeurs sur Player et Windows et non pas des références ?

  9. #9
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 39
    Points : 31
    Points
    31
    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
    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
    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
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Points : 1 176
    Points
    1 176
    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