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 variable globale C++


Sujet :

C++

  1. #1
    Membre du Club
    Problème avec variable globale C++
    Bonsoir à tous;

    J'ai un souci avec une portion de mon code c++, peut être que ça parait facile mais pour moi non à l'heure qu'il est car j'ai passé toute ma journée sans le réussir.

    Mon problème est que j'ai déclaré une variable comme static dans une classe(classe bateau) comme vous indique le code ci-dessous:

    bateau.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
    class bateau{
     
    	private: 
    		string nomb;
    		float longb;
    		float largb;
    		string annee;
    		Categorie categorie; // qui est soit MONOCOQUES ou MULTICOQUES
    		float tpsTraverse;
    		set<sponsors*> listeSponsor;
    		skipper * chefDeBord;//le chef de bord(skipper)
    		routeur * routeurs;//  (le routeur)
     
    	public: 
     
    		static list<bateau*> listeBateau; // il s'agit de cette variable
     
    		enum Categorie{MONOCOQUES,MULTICOQUES}; //les bateaux dans notre cas sont de ces deux type
    		typedef enum Categorie Categorie;
    		//constructeur
    		bateau( string nomb, float longb, float largb, string annee, Categorie cat);
     
    };
    #endif


    et dans un autre fichier j'utilise ma variable en y ajoutant des objets de type bateau

    Menu.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
    void Menu::creationBateaux(string fileName){
     	ifstream fichier(fileName.c_str(),ios::in);
        if(fichier)
    	{       
    		string ligne;
    		string element;
    		string tabBateau[5]; //tableau qui contiendra les caracteristique du futur bateau
    		int index,catBat;float longb,largb;
    		while(getline(fichier,ligne)){
    			index=0;
    			 stringstream lig(ligne);
        		 while (std::getline(lig, element, ':')){//decouper chaque ligne en ses composants
        		 	tabBateau[index]=element; //on stocke chaque element dans une cellule du tableau
                 	index++;					//
        		}
        		//on cree ici le bateau dont les caracteristiques sont dans le tableau
        		longb=stof(tabBateau[1]);//convertir en float la long du bateau
        		largb=stof(tabBateau[2]);// convertir la larg du du bateau en float
        		catBat=stoi(tabBateau[4]);//categorie du bateau qui est un int, soit 0 soit 1
        		//cout<<tabBateau[0]<<" "<<tabBateau[1]<<" "<<tabBateau[2]<<" "<<tabBateau[3]<<" "<<tabBateau[4]<<endl;
        		if(catBat==1)//on construit un bateau de catégorie 2 (multicoque)
        		{
        			bateau b(tabBateau[0],longb,largb,tabBateau[3],bateau::MULTICOQUES);
        			//b.afficheBateau();
        			//this->listeBateau.push_back(&b);
        			bateau::listeBateau.push_back(&b);
        		}
        		else if(catBat==0) //on construit un bateau monocoque(cat 1)
        		{
        			bateau b(tabBateau[0],longb,largb,tabBateau[3],bateau::MONOCOQUES);
        			//b.afficheBateau();
        			bateau::listeBateau.push_back(&b);
        			//this->listeBateau.push_back(&b);
        			//(*(bateau::listeBateau.begin()))->afficheBateau();
        		}
    		}
    		fichier.close();
        }
        else
           cerr << "Impossible d'ouvrir le fichier !"<<endl;
       //return this->listeBateau;
       (*(bateau::listeBateau.begin()))->afficheBateau();
            // 0;
     }


    et enfin dans mon fichier qui contient le main, je fais ceci:

    main.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
    extern list<bateau*>bateau::listeBateau; //definition de la liste d'instance bateau
    int main(int argc, char const *argv[])
    {
     
    	Menu menu; list<bateau*> liste;
    	//liste=menu.getListeBateau();
    	//Course course("N° 1");
    	menu.creationBateaux("bateau.txt");
    	cout<<bateau::listeBateau.size()<<endl;
    	list<bateau*>::iterator it =bateau::listeBateau.begin();
    	while(it!=bateau::listeBateau.end()){
    		(*it)->afficheBateau();
    	}
    }

    le problème, quand j'affiche le contenu de ma variable static dans ma fonction void Menu::creationBateaux(string fileName) tout se passe bien il m'affiche bien les objets à l'intérieur
    mais dans le main, il me donne ceci
    &#65533;+&#65533;&#65533;y""
    G0&#65533;(!p&#65533;7 ;"
    )!&#65533;7 &#65533;(!&#65533;&#65533;7 e
    @&#65533; &#65533;'!&#65533;7 &#65533;&#65533;"
    &#65533;o b'!&#65533;&#65533;7 &#65533;&#65533;
    P&#65533;&#65533;&#65533;'!P&#65533;7 p&#65533;&#65533;
    &#65533;&#65533; J'!&#65533;&#65533;7 &#65533;&#65533;
    @&#65533;z'!@&#65533;7 &#65533;8l>&#65533;
    &#65533;&#65533;L&#65533;(! &#65533;7 &#65533;x
    &#65533;&#65533;&#65533;_&#65533;"
    0&#65533;Y&#65533;(!&#65533;&#65533;7 (!&#65533;&#65533;7 &#65533;&#65533;"
    P"^C&#1206;"
    et ce qui est paradoxale, la taille de ma liste( variable static) s’incrémente à chaque ajout.
    Je précise que j'ai pas de problème d'inclusion en tout cas rien n'est signalé concernant.
    Merci d'avance.

  2. #2
    Expert confirmé
    Bonjour,

    Je ne comprends pas comment le compilateur comprend la ligne 1 du main().
    Le mot extern permet d'indiquer qu'une variable/fonction/template est créée ailleurs et qu'il ne faut pas la recréer ici.
    Ici je le comprend comme il existe dans un namespace nommé bateau une variable nommée listeBateau.

    Or ici on a défini un type bateau, et déclaré un champ statique listeBateau. champ qui ne semble défini nulle part.
    Pour le définir il faudrait la ligne list<bateau*> bateau::listeBateau; donc sans le extern.

  3. #3
    Membre du Club
    Dalfab, merci pour votre reponse. En fait c'est parce que je savais plus quoi faire, si non j'avais commencer par faire une definition de ce genre dans le fichier bateau.cpp mais j'avais le même problème notamment cet affichage bizarre.

  4. #4
    Membre du Club
    En plus lorque j'ajoute un autre objet dans listeBateau mais dans le main comme ceci

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    bateau b3("b3",200.00,150.00,"2007",bateau::MONOCOQUES);
    	bateau::listeBateau.push_back(&b3);


    il le l'affiche bien, mais tout ajout que fais dans ma fonction void Menu::creationBateau(string fileName) ne s'affiche correctement que si je fais un cout dans la fonction mais pas dans le mail

    Nom: b3,Long: 200, Large: 150, Année: 2007, Cat: 1, TT: 0 / /l'objet b3 ajouter dans le main
    &#65533;+&#65533;&#65533;y""
    G0&#65533;(!p&#65533;7 ;"
    )!&#65533;7 &#65533;(!&#65533;&#65533;7 e
    @&#65533; &#65533;'!&#65533;7 &#65533;&#65533;"
    &#65533;o b'!&#65533;&#65533;7 &#65533;&#65533;
    P&#65533;&#65533;&#65533;'!P&#65533;7 p&#65533;&#65533;
    &#65533;&#65533; J'!&#65533;&#65533;7 &#65533;&#65533;
    @&#65533;z'!@&#65533;7 &#65533;8l>&#65533;
    &#65533;&#65533;L&#65533;(! &#65533;7 &#65533;x
    &#65533;&#65533;&#65533;_&#65533;"
    0&#65533;Y&#65533;(!&#65533;&#65533;7 (!&#65533;&#65533;7 &#65533;&#65533;"

  5. #5
    Expert confirmé
    Attention, ta liste contient des adresses de bateau, donc toutes doivent correspondre à des bateau qui restent en mémoire. Quand tu écris :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    {
    	bateau b(tabBateau[0],longb,largb,tabBateau[3],bateau::MULTICOQUES);
    	bateau::listeBateau.push_back(&b);
    }
    Dès la sortie de l'accolade le bateau b disparait et l'adresse mise dans listeBateau ne correspond à plus rien de valide.
    Sinon il faire :
    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
    std::liste<bateau>  listeBateau;   // désormais c'est une liste de bateau
    {
    	bateau  b(tabBateau[0],longb,largb,tabBateau[3],bateau::MULTICOQUES);
    	bateau::listeBateau.push_back( std::move(b) );  // okay, c'est un bateau entier qui est mémorisé
    	// ou
    	bateau::listeBateau.emplace_back( tabBateau[0],longb,largb,tabBateau[3],bateau::MULTICOQUES );
    }
    //ou
    std::list<std::unique_ptr<bateau>>  listeBateau;  // liste de pointeur qui sont propriétaires de bateau
    {
    	auto pt = std::make_unique<bateau>(tabBateau[0],longb,largb,tabBateau[3],bateau::MULTICOQUES);
    	bateau::listeBateau.push_back( std::move(pt) );  // okay, c'est un pointeur 'owner' de bateau qui est mémorisé
    	// ou
    	bateau::listeBateau.emplace_back( std::make_unique<bateau>(tabBateau[0],longb,largb,tabBateau[3],bateau::MULTICOQUES) );
    }
    // autre solution (mais est mauvaise...)
    std::liste<bateau*>  listeBateau;  // tu gardes ton type initialement prévu
    {
    	bateau*  pt = new bateau(tabBateau[0],longb,largb,tabBateau[3],bateau::MULTICOQUES);
    	bateau::listeBateau.push_back( pt );  // semble okay mais attention qui libérera le bateau créé ?
    }

  6. #6
    Membre du Club
    Merci beaucoup, j'ai trouvé le problème. EN fait quand j'ai fait une allocation dynamique de mes objetcs ca marhcé. Je sais pas pourquoi mais il me semble que tous les objets étaient créés avec la meme reference (b).