Pourquoi déjà du C et pas du vrai C++ ?
%d, c'est pour un entier, pas un char, c'est %c.
Ensuite, on ne sait pas quel est le type de Chrom_1->bit(a)
Version imprimable
Pourquoi déjà du C et pas du vrai C++ ?
%d, c'est pour un entier, pas un char, c'est %c.
Ensuite, on ne sait pas quel est le type de Chrom_1->bit(a)
Je suppose que tu fais référence au fait que j'utilise printf et pas cout?Citation:
Envoyé par Miles
C'est parce qu'il s'agit d'une bibliothèque qui a plus de 10 ans, elle a été upgradée vers le C++, mais tous les standards récents ne sont pas inclus.
J'ai juste mis ça parce que ça m'évitait de rajouter stdio (je ne me trompe pas, il s'agit bien de la librairie des i/o standards?)
Oui mais c est un unsigned int.Citation:
%d, c'est pour un entier, pas un char, c'est %c.
C'est un short.Citation:
Ensuite, on ne sait pas quel est le type de Chrom_1->bit(a)
Mais là tu me parles juste de l'affichage et de la valeur renvoyée, quel est le rapport avec le test conditionnel?Code:
1
2
3 short bit(unsigned int a) const { return(data[a]); }
Ah oui, zut, je me suis planté :aie:
Pour les flux standards du C++, c'est <iostream>
C'est bizarre, tout de même. Essaie avec 1U à la place de 1 ?
C'est fait, j'obtiens la même sortie. Mais je ne comprends pas ce que c'était censé changer.Citation:
Envoyé par Miles
C'est bien là que tu veux que je rajoute le 'U'?:
Code:
1
2
3
4
5
6
7
8
9
10
11
12 short bit(unsigned int a, unsigned int c) const { printf("c = %d ", c); //delete switch(c) { case 1U: {printf("reading in 1: %d\n",Chrom_1->bit(a)); return(Chrom_1->bit(a));} break; default: {printf("reading in 2: %d\n",Chrom_2->bit(a)); return(Chrom_2->bit(a));} } }
J'ai trouvé, je ne faisais pas appel à la bonne fonction.
Merci d'avoir essayé de m'aider. ;)
Non.Citation:
Envoyé par Miles
<iostream> => définitions de std::cout, cin, cerr, clog
<iosfwd> => déclarations anticipées de std::istream et std::ostream => pour les .h
<istream> => définition de std::istream => pour définir les opérateurs d'extraction et autres fonctions de désérialization
<ostream> => définition de std::ostream => pour définir les opérateurs d'insertion et autres fonctions de sérialization
<fstream> => définition des std::*fstream => quand on veut définir un fichier
<sstream> => définition des std::*sstream => quand on veut définir un flux chaîne
...
+1 pour les "..." :aie:Citation:
Envoyé par Luc Hermitte
Merci Luc, je viens de tomber sur des istream et ostream.
Ca m'évite de poser la question. :)
Edit:
Ah, en fait:
Mon code étant celui-ci:Citation:
Project\C++\GATest\GADiploidGenome.h(37) : error C2061: erreur de syntaxe : identificateur 'istream'
Project\C++\GATest\GADiploidGenome.h(38) : error C2061: erreur de syntaxe : identificateur 'ostream'
Code:
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 #include <GADiploid.h> #include <iosfwd> #include <istream> #include <ostream> class GADiploidGenome : public GADiploid { public: GADefineIdentity("GADiploid", 421); static void Initializer(GAGenome&); static int Mutator(GAGenome&, float); static float Comparator(const GAGenome&, const GAGenome&); static float Evaluator(GAGenome&); static int Crossover(const GAGenome&, const GAGenome&, GAGenome*, GAGenome*); public: GADiploidGenome(unsigned int len, GAGenome::Evaluator f, void * u); GADiploidGenome(const GADiploid & orig); GADiploid& operator=(const GAGenome & arg); virtual ~GADiploidGenome(); virtual GAGenome *clone(GAGenome::CloneMethod) const ; virtual void copy(const GAGenome & c); virtual int equal(const GAGenome& g) const ; virtual int read(istream & is); virtual int write(ostream & os) const ; GAListGenome<int> & path(int i){ return *list[i]; } int npaths() const { return n; } int length() const { return l; } protected: int n, l; GAListGenome<int> **list; };
Je croyais que c'était suffisant pour les .h ?
(lignes incriminées en rouge)
std:: pour tout ce qui sort de la bibliothèque standard C++.
Et comme je disais, pour une déclaration dans un .h, <iosfwd> est préférable.
<istream> et <ostream> deviennent par contre nécessaires dans le .cpp pour s'occuper de l'implémentation.
Merci pour vos indications.
Une autre question:
J'ai du mal à saisir le sens de cette écriture.Code:GAGenome(Initializer i=0, Mutator m=0, Comparator c=0);
- Est-ce à dire que la fonction va utiliser les valeurs i, m et c pour ses opérations, mais que celles-ci seront remises à 0 après son exécution?
- Ou est-ce qu'il s'agit de valeurs par défaut attribuées si i, m et c n'ont pas déjà de valeur?
Ces interprétations me semblent toutes deux assez étranges.
ça veut dire que tu peux appeler la fonction ainsi:
Et cela sera équivalent à GAGenome(0, 0, 0);Code:GAGenome()
C'est le principe des "Paramètres par défaut" de C++.Code:
1
2
3
4 GAGenome(); //Equiv. GAGenome(0, 0, 0); GAGenome(1); //Equiv. GAGenome(1, 0, 0); GAGenome(1, 2); //Equiv. GAGenome(1, 2, 0); GAGenome(1, 2, 3); //Equiv. GAGenome(1, 2, 3);
Note: l'EDI de Visual C++ n'aime pas trop ça. Pour les autres EDI, j'ignore comment ils s'en sortent. Dans tous les cas, seul l'EDI a des problèmes: Le compilateur marche toujours bien.
D'accord je vois, merci beaucoup.
J'ai un problème avec un warning:
Citation:
Project\C++\GATest\GADiploidGenome.h(50) : warning C4584: 'GADiploidGenome' : la classe de base 'GAGenome' est déjà une classe de base de 'GADiploid'
Project\C++\GATest\ga\GAGenome.h(175) : voir la déclaration de 'GAGenome'
Project\C++\GATest\GADiploid.h(31) : voir la déclaration de 'GADiploid'
En effet GAGenome est déjà une classe de base de GADiploid, mais le problème est que j'en ai besoin pour mon constructeur.Code:
1
2
3
4
5
6 class GADiploidGenome : public GADiploid, public GAGenome { [...] }
Si je le supprime:Code:
1
2
3
4
5
6
7
8
9
10
11 GADiploidGenome:: GADiploidGenome(unsigned int len, GAGenome::Evaluator f, void * u) : GADiploid(len), GAGenome(DEFAULT_GADIPL_INITIALIZER, DEFAULT_GADIPL_MUTATOR, DEFAULT_GADIPL_COMPARATOR) { Evaluator(f); //userData(u); crossover(DEFAULT_GADIPL_CROSSOVER); // assign the default sexual crossover nx=minX=maxX=0; resize(len); }
J'obtiens:Code:class GADiploidGenome : public GADiploid//, public GAGenome
Ce qui semble logique.Citation:
Project\C++\GATest\GADiploidGenome.cpp(39) : error C2614: 'GADiploidGenome' : initialisation de membre non conforme : 'GAGenome' n'est ni une base ni un membre
Si ce n'était qu'un warning je pourrais passer outre, mais de mettre deux fois GAGenome en base entraîne un certain nombre d'erreur du type:
Code concerné:Citation:
Project\C++\GATest\GADiploidGenome.h(92) : error C2385: accès ambigu de '_evaluated' dans 'GADiploidGenome'
est peut-être le '_evaluated' en base 'GAGenome::_evaluated'
ou le '_evaluated' en base 'GAGenome::_evaluated'
En sachant que _evaluated est défini dans GAGenome comme:Code:
1
2 short gene(unsigned int x, short value, unsigned int c = 0) {_evaluated = gaFalse; return((bit(x,c) == value) ? value : bit(x,value,c));}
Avez-vous une double idée de comment résoudre cette double contradiction, d'une classe dont j'ai besoin dans mon constructeur mais dont l'appel crée en double mes constantes globales?Code:
1
2 protected: GABoolean _evaluated; // has this genome been evaluated?
A l'aide du mot clé virtual pour l'héritage ?
C'est-à-dire? En mettant virtual devant toutes les fonctions et membres de GAGenome.h?
Le problème est que cette classe est une classe standard de la bibliothèque et donc que je ne peux pas y toucher.
Je ne peux modifier les fichiers GADiploid et GADiploidGenome.
Non, héritage virtuel, tu fais un virtual GAGenome.
Tu veux dire en écrivant:
?Code:class GADiploidGenome : public GADiploid, public virtual GAGenome
Note:
J'ai contourné le problème hier en remplaçant:
par:Code:
1
2 GADiploid(len), GAGenome(DEFAULT_GADIPL_INITIALIZER, DEFAULT_GADIPL_MUTATOR, DEFAULT_GADIPL_COMPARATOR)
et en créant le constructeur ad-hoc (très utiles d'ailleurs les paramètres par défaut), mais ça m'intéresse quand même pour ma culture générale.Code:GADiploid(len, DEFAULT_GADIPL_INITIALIZER, DEFAULT_GADIPL_MUTATOR, DEFAULT_GADIPL_COMPARATOR)
Code:
1
2 GADiploid::GADiploid(unsigned int s, GAGenome::Initializer i=0, GAGenome::Mutator m=0, GAGenome::Comparator c=0) : GABinaryString(s), GAGenome(i, m, c)
GADiploid hérite de GAGenome ? Si oui, c'est le problème de l'héritage en diamand, et ça se résoud avec virtual, comme tu l'as fait.
GADiploid hérite effectivement de GAGenome
J'ai essayé d'appliquer ce que tu suggères:
--------------------------------------------------------------------------Code:class GADiploidGenome : public GADiploid, public virtual GAGenome
Parenthèse:
Dans ma correction, j'avais supprimé public virtual GAGenome des classes de base de GADiploidGenome et j'avais fait passer les argument nécessaires à l'instantiation de GAGenome à travers GADiploid.
Ta solution est plus élégante, c'est pour ça que j'aimerais l'appliquer.
--------------------------------------------------------------------------
Mais je me retrouve maintenant avec une floppée d'erreurs du type:Code:class GADiploid : public GABinaryString, public virtual GAGenome
GADiploidGenome::copy(const GAGenome & orig)Citation:
Project\C++\GATest\GADiploidGenome.cpp(93) : error C2635:: impossible de convertir un(e) 'GAGenome*' en un(e) 'GADiploidGenome*'; conversion à partir d'une classe de base virtuelle implicite
Project\C++\GATest\ga\GAGenome.h(175) : voir la déclaration de 'GAGenome'
Project\C++\GATest\GADiploidGenome.h(49) : voir la déclaration de 'GADiploidGenome'
{
if(&orig == this) return;
const GADiploidGenome* c =
DYN_CAST(const GADiploidGenome*, &orig);
if(c) {
GAGenome::copy(*c);
GADiploid::copy(*c);
nx = c->nx; minX = c->minX; maxX = c->maxX;
}
}
Il refuse de convertir la classe de base, maintenant qu'elle est virtuelle. 8O
(du moins c'est ce que je comprends)