C++ classe retour fonction et affichage

Résolu/Fermé
velderama Messages postés 199 Date d'inscription mardi 26 février 2008 Statut Membre Dernière intervention 11 mai 2011 - 18 mars 2008 à 18:15
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 - 20 mars 2008 à 08:39
Bonjour,

j'ai la classe Liste.cpp suivante : " prends un fichier et retourne le nombre de mot du fichier "

int Liste::ajoutMot(ifstream ifs){

string line;
int pos;
int nbmot = 0;
//tant qu'on n'a pas atteint la fin de fichier
for(unsigned no_line = 0;std::getline(ifs,line);++no_line){
unsigned beg = 0;
unsigned end = 1;

for(unsigned no_mot=0;end < line.size();++no_mot){

//On positionne a la fin du mot la variable "end"
for(;end < line.size() && !is_delim(line[end]);++end);//...is_delim(line[end])...

std::string mot(line,beg,end-beg);//recuperation du mot
pos=pos+beg;
if(mot.size()>=3 ){
nbmotlongref++;
mots[mot] = (pos);
}//if(mot.size()>=3)
beg = end + 1;
end = beg + 1;
}//fin ligne(...line.size())

}//fin fichier getline(ifs,line)

return nbmot;

}//ajoutMot

puis j'ai une classe Affichage qui doit afficher le nombre de mot du fichier :
....
#include "Liste.h"

using namespace std;

int main(int argc, char *argv[]){

const char *filename = argv[1];
ifstream ifs(argv[1]);// On ouvre le fichierRef en lecture

Liste liste;//creation d'un objet de la classe Liste
int nbmot= liste.ajoutMot(ifs);

Et la il ne veut pas de la ligne int nbmot= liste.ajoutMot(ifs); ??

" le logiciel génère un ios_base.h"

Message d'erreur dans la "console":
738 D:\ios_base.h `std::ios_base::ios_base(const std::ios_base&)' is private
16 D:\affichage.cpp within this context

Où est ce que je me suis craqué ??
Merci d'avance
A voir également:

5 réponses

Mahmah Messages postés 496 Date d'inscription lundi 17 septembre 2007 Statut Membre Dernière intervention 22 juin 2010 125
18 mars 2008 à 20:39
Bonjour,

Je ne sais pas trop si cela peut être la cause de ce problème, mais en tout cas c'est pas très beau...

int Liste::ajoutMot(ifstream ifs)

L'argument est passé par copie.

D'ailleurs je n'ai pas trouvé le copy-constructor de fstream, donc si c'est une erreur de compilation, elle est là.

M.
0
velderama Messages postés 199 Date d'inscription mardi 26 février 2008 Statut Membre Dernière intervention 11 mai 2011 10
19 mars 2008 à 13:09
Merci ! effectivement le copie fstream ne marchait pas .
0
velderama Messages postés 199 Date d'inscription mardi 26 février 2008 Statut Membre Dernière intervention 11 mai 2011 10
19 mars 2008 à 13:22
Par contre
J'arrive pas a lancer l'application
Message d'erreur :

[Linker error] undefined reference to `Liste::mots'
[Linker error] undefined reference to `Liste::nbmot' ,

J'ai la classe Liste.h

#ifndef Liste_H
#define Liste_H
using namespace std;
class Liste
{
public:
Liste();

inline bool is_delim(char c);//le delimiteur entre les mots
static int ajoutMot(ifstream & ifs);//ajoute les mots du fichier f dans le map
static map<string , int> getMap();//recupere le map
static int getNb(); // retourne le nombre de mot
void setNb(int i){nbmot = i;} //MAJ du nombre de mots
void setMap(map<string , int> m){mots = m;}//MAJ du map

private:
static ifstream fic;
static map<string , int> mots;
static int nbmot;
};

#endif

J'ai des problemes de lien appriori ?!
PS : je débute avec C++...

Merci de votre aide
0
Mahmah Messages postés 496 Date d'inscription lundi 17 septembre 2007 Statut Membre Dernière intervention 22 juin 2010 125
19 mars 2008 à 14:40
C'est à cause des statics.

Comme tu souhaites ici n'avoir qu'une seule instance de tes variables pour tous tes objets, (bizarre d'ailleurs...) cette instance doit être déclarée quelque part.

class Truc
{
private:
    static int m_i;
};

// Truc.cpp

int Truc::m_i;
ou
int Truc::m_i = 27;


Ainsi ton instance unique de ta variable existe et peut-être linkée. Les statics dans une classe revient à faire du C. (D'ailleurs c'est compilé comme du C)

M.
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
19 mars 2008 à 14:34
C'est des problèmes de lien : oui, mais aussi de définition.
écrire "static int nbmot;" est équivalent à "static int fct(int);" tu déclare une variable (ou une fonction) sans lui dire quoi mettre dedans, donc forcement le compilateur cherche... et ne trouve pas.
Dans le fichier ou tu défini le constructeur List::List(), il faut aussi que tu définisse Liste::nbmot; la syntaxe est je crois:
int Liste::nbmot=0;
Je croi que si tu fait static int nbmot=0 directement dans la class, tu risque d'avoir une erreur de multi definition.

je suppose que le problème est le même pour "mots", mais comme je ne connaît pas les map je ne peux pas t'en dire plus.
0
Mahmah Messages postés 496 Date d'inscription lundi 17 septembre 2007 Statut Membre Dernière intervention 22 juin 2010 125
19 mars 2008 à 14:47
static int nbmot=0; peut marcher (à moins qu'il ne doive être obligatoirement const également) cependant, ce n'est pas standard. Mieux vaut donc éviter.

M.
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297 > Mahmah Messages postés 496 Date d'inscription lundi 17 septembre 2007 Statut Membre Dernière intervention 22 juin 2010
19 mars 2008 à 15:20
avec un const, ça doit être standard.
Si ce n'est pas standard, autant dire que ça ne fonctionne pas. Il faut éviter dans la mesure du possible de faire du code non standard (car non portable, et pas forcement pérenne, déjà que le standard...)
0
velderama Messages postés 199 Date d'inscription mardi 26 février 2008 Statut Membre Dernière intervention 11 mai 2011 10
19 mars 2008 à 15:26
Merci pour vos aides :

code devient : "liste.h"

#ifndef Liste_H
#define Liste_H
using namespace std;
class Liste
{
public:


int ajoutMot(ifstream & ifs);//ajoute les mots du fichier ifs dans le map
map<string , int> getMap();//recupere le map
int getNb(); // retourne le nombre de mot
void setNb(int i){nbmot = i;}//MAJ du nombre de mots
void setMap(map<string , int> m){mots = m;}//MAJ du map

private:
ifstream fic;
static map<string , int> mots;
static int nbmot;
};

#endif


Et dans "liste.cpp" ------>

#include <iostream>
#include <fstream>
#include <string>
#include <map>

//j'appelle la classe "interface" de celle-ci
#include "liste.h"

//initialisation(definition) des variables privé
map<string , int> Liste::mots;
int Liste::nbmot;

.... (la suite est la meme qu'au dessus )

Ps : pour acceder aux variables privées il faut mettre static au debut je sais pas pourquoi sinon cela ne marche pas sans?! (erreur de "Linkage")

Si quelqu'un a compris pourquoi il pourra expliqué !

Merci
0
Mahmah Messages postés 496 Date d'inscription lundi 17 septembre 2007 Statut Membre Dernière intervention 22 juin 2010 125
19 mars 2008 à 15:46
Si tes variables n'ont pas à être static il n'y a pas à les déclarer comme tel juste pour que ça compile...

Il pourrait être utile de revenir sur ton PS:
<<Ps : pour acceder aux variables privées il faut mettre static au debut je sais pas pourquoi sinon cela ne marche pas sans?! (erreur de "Linkage") >>

Quelle est le compilateur utilisé et qu'elle est l'erreur exacte ?
Et ton implémentation nécessite-t-elle que ces variables soient déclarées statiques ou non ?


En passant je dirais bien que le SetMap est pas très très beau... passer toute une map par copie... UUuuuuhg!
Idem pour le getMap.

M.
0
velderama Messages postés 199 Date d'inscription mardi 26 février 2008 Statut Membre Dernière intervention 11 mai 2011 10 > Mahmah Messages postés 496 Date d'inscription lundi 17 septembre 2007 Statut Membre Dernière intervention 22 juin 2010
19 mars 2008 à 15:53
Exactement je les ai enlevé car ils me servent pas (et meme j'aurai passé par reference ) c'etait dans la premiere phase de creation de mes classes...!!
J'utilise dev-cpp version 4.9.9.2 que j'installe dans ma clé usb (peut etre que cela vient de là?)
sinon les erreurs sont comme au dessus [Linkin error]... sans static devant ces variables
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
19 mars 2008 à 15:50
houlà !
ce que tu dit est faut. Il n'y a pas besoin de mettre static, sinon, ça se saurai.
Enlève static, MAIS plus besoin d'initatliser tes variables à part dans le .cpp, tu initialise tes variables dans le constructeur.
Class A{ A(); private: int a,b,c;}
dans .Cpp :
A::A():a(0),b(5),c(10)
{}
Il faut bien que tu arrive à distinguer l'objet de la class. A est une class, mais lorsque tu fait A obj; obj est un obj de type A, ou une instance de A. Si tu a obj1 et obj2, si a est un membre static et b non, tu aura obj1.a==obj2.a à n'importe quel instant du programme, 'a' est relier à la class et non à l'objet. par contre, en toute généralité obj1.b!=obj2.b
C'est pour cela que la déclaration et l'initialisation des ces deux variables sont différentes, A::a est unique alors que A::b n'a aucun sens, aucune valeur en dehors d'un objet.
0
velderama Messages postés 199 Date d'inscription mardi 26 février 2008 Statut Membre Dernière intervention 11 mai 2011 10
19 mars 2008 à 15:58
Merci tu as raison ! j'ai enlevé et ca marche !
Je comprenais pas trop comment definir les variables privées ...

Je les declarais dans "liste.h" sans les initialiser dans "liste.cpp" comme ceci

map<string , int> Liste::mots;
int Liste::nbmot;
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297 > velderama Messages postés 199 Date d'inscription mardi 26 février 2008 Statut Membre Dernière intervention 11 mai 2011
20 mars 2008 à 08:39
J'avais bien compris ;-)
Par contre ne te focalise pas sur privée ou non, c'est strictement pareil du point de vu codage, ce qui change c'est les droits d'utilisation en dehors de la classe !
0