Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème de portée

    17 juillet 2019 à 1:39:25

    Bonjour,

    Je m'entraîne dans la programmation à objets en C++. Je suis entrain d'expérimenter les classes amies, tel qu'un service qui regrouperait tous les accesseurs d'une classe, ou une classe matérialisant la relation entre deux classes.

    Tout se passait bien, l'environnement de développement (MVSC 2019) ne m'indiquait aucun avertissement... Jusqu'à la compilation. 

    Une cascade de messages d'erreur, qui me mit à genoux. Notamment l'erreur constante : "Person" : identificateur introuvable, ou bien d'autres erreurs concernant la portée.

    Dans mon code (et dans ma tête) tout parait OK, l'#include de headers, rien de ce qui est en rapport avec la portée ne me parait loufoque... J'ai cherché pas mal de temps sur internet et personnellement, mon niveau dans le langage C++ n'est pas assez élevé pour relever l'erreur. Merci d'avance pour l'aide.

    Voici Mon code (au complet) :

    Person.h

    #pragma once
    
    #include <string>
    #include <vector>
    
    #include "Fly.h"
    #include "Relationships.h"
    #include "Accessors.h"
    
    #ifndef __PERSON_07172019__
    #define __PERSON_07172019__
    
    class Person
    {
    	/** Friend classes */
    	friend class Relationships;
    	friend class Accessors;
    
    	public:
    		/** @brief Default ctor */
    		Person( std::string name = "default" );
    
    	private:
    		/** Member variables */
    		const std::string name;
    		/** @brief Vector of pointers on Fly type */
    		std::vector<Fly*> flyVector;
    };
    
    #endif // __PERSON_07172019__

    Person.cpp

    #include <string>
    #include "Person.h"
    
    Person::Person( std::string name ) : name( name )
    {
    }
    

    Fly.h

    #pragma once
    
    #include <string>
    #include <vector>
    
    #include "Person.h"
    #include "Relationships.h"
    #include "Accessors.h"
    
    #ifndef __FLY_07172019__
    #define __FLY_07172019__
    
    class Fly
    {
    	/** Friend classes */
    	friend class Relationships;
    	friend class Accessors;
    	
    	public:
    		/** @brief Default ctor */
    		Fly( std::string from, std::string to );
    
    	private:
    		/** Member variables */
    		const std::string from;
    		const std::string to;
    		/** @brief Vector of pointers on Person type */
    		std::vector<Person*> personVector;
    };
    
    #endif // __FLY_07172019__

    Fly.cpp

    #include <string>
    #include "Fly.h"
    
    Fly::Fly( std::string from, std::string to ) : from( from ), to( to )
    {
    }
    

    Relationships.h

    #pragma once
    
    #include "Person.h"
    #include "Fly.h"
    
    #ifndef __RELATIONSHIPS_07172019__
    #define __RELATIONSHIPS_07172019__
    
    class Relationships
    {
    	public:
    		/** Pseudo-ctor */
    		static Relationships& Instance();
    
    		/** member functions */
    		static void AddPassengerToFly( Person& person, Fly& fly );
    		static void RemovePessengerFromFly( Person& person, Fly& fly );
    
    	private:
    		/** Singleton */
    		Relationships();
    		static Relationships instance;
    };
    
    #endif // __RELATIONSHIPS_07172019__

    Relationships.cpp

    #include <algorithm>
    #include <iterator>
    
    #include "Relationships.h"
    #include "Person.h"
    #include "Fly.h"
    
    Relationships& Relationships::Instance()
    {
    	return Relationships::instance;
    }
    
    void Relationships::AddPassengerToFly( Person& person, Fly& fly )
    {
    	person.flyVector.push_back( &fly );
    	fly.personVector.push_back( &person );
    }
    
    void Relationships::RemovePessengerFromFly( Person& person, Fly& fly )
    {
    	auto personIteratorPos { std::find( person.flyVector.begin(), person.flyVector.end(), fly ) };
    	person.flyVector.erase( personIteratorPos );
    
    	auto flyIteratorPos { std::find( fly.personVector.begin(), fly.personVector.end(), person ) };
    	fly.personVector.erase( flyIteratorPos );
    }

    Accessors.h

    #pragma once
    
    #include <string>
    
    #include "Person.h"
    #include "Fly.h"
    
    #ifndef __ACCESSORS_07172019__
    #define __ACCESSORS_07172019__
    
    class Accessors
    {
    	public:
    		/** Pseudo-ctor */
    		static Accessors& Instance();
    
    		/** Member functions for Person */
    		static std::string GetName( Person& person );
    		static std::string GetFlyVector( Person& person );
    
    		/** Member functions for Fly */
    		static std::string GetFrom( Fly& fly );
    		static std::string GetTo( Fly& fly );
    		static std::string GetPersonVector( Fly& fly );
    
    	private:
    		/** Singleton */
    		static Accessors instance;
    		Accessors();
    };
    
    #endif // __ACCESSORS_07172019__

    Accessors.cpp

    #include "Accessors.h"
    #include "Person.h"
    #include "Fly.h"
    
    Accessors& Accessors::Instance()
    {
    	return Accessors::instance;
    }
    
    std::string Accessors::GetName( Person& person )
    {
    	return person.name;
    }
    
    std::string Accessors::GetFlyVector( Person& person )
    {
    	std::string toReturn;
    
    	for ( auto element : person.flyVector )
    		toReturn += Accessors::GetFrom( *element ) + ' ' + Accessors::GetTo( *element ) + " ; ";
    
    	return toReturn;
    }
    
    std::string Accessors::GetFrom( Fly& fly )
    {
    	return fly.from;
    }
    
    std::string Accessors::GetTo( Fly& fly )
    {
    	return fly.to;
    }
    
    std::string Accessors::GetPersonVector( Fly& fly )
    {
    	std::string toReturn;
    
    	for ( auto element : fly.personVector )
    		toReturn += Accessors::GetName( *element ) + " ; ";
    
    	return toReturn;
    }
    



    • Partager sur Facebook
    • Partager sur Twitter
      17 juillet 2019 à 9:06:30

      Salut,

      Pour qu'on puisse mieux t'aider, il faudrait préciser les erreurs exactes, et aussi les lignes (et fichiers) dans lesquelles chacune apparait.

      Mais en C++, tu n'inclut qu'une seule fois un fichier dans un autre (je sais c'est mal dit). Tu utilises un mécanisme pour ça : #ifndef ... #define ... #endif, ou bien #pargma once (c'est d'ailleurs redondant d'utiliser les deux).

      Là où je veux en venir, c'est que si le compilateur inclut une fois le fichier, il ne va pas le réinclure, alors que le fichier en train d'être complié en a besoin. Des erreurs peuvent donc apparaitre, telles que 'Person identificateur introuvable". Dans ce cas, il y a deux solutions (à ma connaissance) :

       - Avoir un fichier qui fait tous les includes (au lieu de le faire dans chaque), pour le faire dans un ordre qui ne pose pas de problème (ce n'est pas toujours possible)

       - Préciser que la classe existe dans les fichiers où tu l'utilise :

      #pragma once
      
      #include "person.h"
      
      // Ici, le compilateur peut croire qu'il ne connait pas Person, alors qu'après l'étape de link il n'y aura pas de problème
      
      // Du coup, tu fais ça :
      class Person;
      
      // Et la, magie, le compilateur est satisfait
      • Partager sur Facebook
      • Partager sur Twitter

      J'aime les bandes dessinées, manhuas, manhwas, mangas, comics... Du coup j'ai fait aralosbd.fr !

        17 juillet 2019 à 12:29:40

        Bonjour,

        Et ici, tu as de belles collisions :
        - "Person.h"  inclut "Fly.h" et "Fly.h" inclut "Person.h" => impossible
        - "RelationShips.h" inclut "Person.h" et "Fly.h" et "Person.h" et "Fly.h" incluent "RelationShips.h" => impossible.

        Il faut impérativement une hiérarchie des besoins. Smiley32 t'a donné la méthode.
        Exemple dans "Fly.h" :
        - pas besoin d'inclure "RelationShips.h", la seule chose qu'il doit savoir est que RelationShips est une class. Il le sait.
        - pas besoin d'inclure "Person.h",  la seule chose qu'il doit savoir est que Person est une class. Il faut ajouter à la place de l'include : class Person;

        En gros les fichiers .h n'ont pas vraiment besoin les uns des autres ici. Par contre pour écrire les .cpp, il faudra ajouter les includes nécessaires.

        • Partager sur Facebook
        • Partager sur Twitter

        En recherche d'emploi.

        Problème de portée

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
        • Editeur
        • Markdown