Salut,
Pour commencer, je vais me permettre quelques remarques au sujet de ta class log...
Un petit rappel, d'abord: les définitions des fonctions template doivent se trouver dans les fichiers d'en-tête.
Ensuite, il semblerait de bon ton d'éviter la copie des objets que tu passe à l'opérateur << de ta classe log...
L'idéal étant de fournir une référence constante vers ces différents objet.
Ainsi, le constructeur serait bien plus à son aise sous la forme de
LoG(const std::string& filename)
et ta surcharge de operator<< le serait également sous la forme de
1 2
| template<typename TYPE>
LoG& operator<<(const TYPE& obj); |
Ainsi, la seule spécialisation partielle sous la forme de
1 2 3 4 5 6
| template<>
Log& Log::operator<< <std::string>(const std::string& obj)
{
log_list.back() += obj;
return (*this);
} |
suffirait-elle (grace au constructeur de la classe std::string qui prend un ... const char*) à travailler aussi bien avec une std::string qu'avec ... un const char* ![;)](https://www.developpez.net/forums/images/smilies/icon_wink.gif)
Pour les autres spécialisations partielle, bien qu'il n'y ait que peu d'avantages à travailler sur des références constantes vers des types primitifs, cela ne fait pas de tort pour autant, donc... autant en profiter ![;)](https://www.developpez.net/forums/images/smilies/icon_wink.gif)
Ensuite (au fait, pour permettre la compilation de handler.cpp, il faut inclure le fichier d'en-tête <cstring> pour disposer de memcpy
).
Ainsi, la définition de la méthode void TABLE::reclip_me(void), m'incite à plusieurs remarques:
i et j sont des compteurs de boucle... l'idée générale étant de déclarer les variables quand on en a besoin, leur déclaration pourrait très bien se faire directement dans la boucle sous les boucles sous la forme de
1 2 3 4
| for(int j=0; j<h; j++)
{
for(int i=0; i<w; i++)
{ |
De plus, et je ne fais ici qu'émettre un avis personnel (que beaucoup partagent d'ailleurs), si le langage accepte les listes de déclarations de variables de même type en les séparant par des virgules, l'idée générale est que le code est bien plus souvent lu qu'il n'est écrit, et que, bien que cela permette de gagner quelques (dixièmes de) secondes lors de l'écriture du code à utiliser cette possibilité, il est préférable de malgré tout veiller à ne faire qu'une déclaration de variable par ligne.
Tu peux de toutes manières faire confiance au compilateur pour optimiser un code qui prendrait la forme de
1 2 3 4
| int Xmin;
int Xmax;
int Ymin;
int Ymax; |
mais tu évite le risque qu'un lecteur un peu distrait ne remarque pas tout de suite qu'il s'agit de... 4 déclarations ![;)](https://www.developpez.net/forums/images/smilies/icon_wink.gif)
En outre, il faudrait que tu sois attentif à gérer les différents avertissement lancés par le compilateur quand il est bien réglé:
Les avertissements ne sont pas tes ennemis, bien au contraire...
Ils t'indiquent que tu prend un risque, malgré le fait que ton code est syntaxiquement correct.
En réglant ton compilateur sur un mode "paranoïaque", tu obtiendrait les avertissements suivants concernant cette méthode:
1 2 3 4 5
| D:\projects\LifeFinder\Source\Tables.cpp||In member function 'void TABLE::reclip_me()':|
D:\projects\LifeFinder\Source\Tables.cpp|189|attention : 'Ymin' may be used uninitialized in this function|
D:\projects\LifeFinder\Source\Tables.cpp|188|attention : 'Xmax' may be used uninitialized in this function|
D:\projects\LifeFinder\Source\Tables.cpp|188|attention : 'Xmin' may be used uninitialized in this function|
D:\projects\LifeFinder\Source\Tables.cpp|189|attention : 'Ymax' may be used uninitialized in this function| |
qui t'indiquent, tout simplement, que tes différentes variables risque d'être utilisées sans que tu ne les aie initialisées de manière correcte, avec tous les risques que cela peut comporter.
Comme la solution est relativement simple, autant "blinder" le code de ce coté là: il suffit, pour les *min, de fournir une valeur plus petite que la valeur minimale que tu dois gérer (ici, sans doute plus petite que 0) et pour les *max, une valeur plus grande que celle que tu dois gérer (par exemple MAX_INT)
Cela pourrait prendre chez toi, étant donné que tu dispose des valeurs v et w, une forme proche de
1 2 3 4
| int Xmin=-1;
int Ymin=-1;
int Xmax=w+1;
int YMax=h+1; |
Cela aura pour résultat immédiat de t'éviter d'avoir, en plus, à gérer le fait que ce soit ou non le premier passage dans la boucle, et donc de t'éviter le test if(begin), étant donné que tu serait sur que les valeurs correspondantes au début sont de nature à forcer la modification
![:D](https://www.developpez.net/forums/images/smilies/icon_biggrin.gif)
De la même manière, si la fonction main() prend des arguments, le premier doit être un int...
Le prototype de main est donc soit
t
1 2 3
| int main(int argc, char* argv[])
{
} |
Enfin, il faut se méfier de la fonction system, qui n'est absolument pas portable...
A vrai dire, c'est surtout du au fait que tu n'est absolument pas sur que la commande que tu invoques existe sur les différents système d'exploitation possibles... Et la cas de "pause" est symptomatique: la commande n'existe que sous windows.
C'est pourquoi, je te conseillerais volontiers de remplacer cette commande honnie s'il en est par l'alternative proposée dans la FAQ
Bien sur, tout ceci ne fait pas avancer ton problème... Mais, comme ces remarques générales sont de nature à te permettre d'améliorer ta manière de programmer et que mon message devient déjà fort long, je vais te laisser méditer dessus, et essayer de trouver un peu de temps pour observer ton code de manière plus détaillée
Partager