parce que :
snprintf(dest, 20, "%-3d %4st%-10.2f", entier, chaine, double);
parce que :
snprintf(dest, 20, "%-3d %4st%-10.2f", entier, chaine, double);
parce que :
snprintf(dest, 20, "%-3d %4st%-10.2f", entier, chaine, double);
class Budget
{
public:
const string &category;
const string &name;
const Currency &value;
Pour commencer, c'est quoi, c'est membre référence ? Les membres
références sont normalement rarissime. (De même que les membres donnés
publiques, d'ailleurs, dans une class qui a aussi des membres privés.)
Budget(char * c, char *n, Currency v);
private:
string categorie;
string nom;
Currency valeur;
}char * est indispensable pour des problèmes de portabilité, je
converti monAMA plutôt 'char const*' ? Sinon tu ne pourras pas passer des chaînes
constantes...
.......Apparemment tu cherches
: ..., categorie(c, std::min(std::strlen(c), std::size_t(80)))
Voire simplement categorie( s ).
Ton 'c' vient d'où alors ? L'intérêt des std::string est justement de
ne pas être obligé de couper les chaînes à cause d'utilisation des
buffeurs de taille fixe ! Par contre, si 'c' est un pointeur invalide
(NULL, non initialisé ou pointant sur une zone de mémoire libérée),
effectivement ça se passera mal...
C'est vrai que quelques coups de string(c) avec un c où strlen(c) vaut
35478945231, ça pourrait poser des problèmes sur beaucoup de systèmes.
Du genre bad_alloc. D'ailleurs, l'existance même d'une chaîne (C ou
std::string) de cette taille est impossible sur pas mal des machines.
Si le poster a réelement à gerer des chaînes de cette longueur, il se
peut bien qu'il a besoin des moyens spéciaux.
On aimerait d'abord comprendre le problème.Tu peux simplement appeler std::random_shuffle(it_begin, in_end) mais
ni le générateur de nombres aléatoires ni la façon d'initialiser son
seed sont spécifiés dans la Norme (§ 25.2.11). Si le résultat n'est
pas assez aléatoire pour toi, tu peux utiliser ton propre générateur
qui gère son seed. Exemple (il y en a d'autres sur le Web) :
....
Chez Boost, par exemple, où à ma site.
....
class Budget
{
public:
const string &category;
const string &name;
const Currency &value;
Pour commencer, c'est quoi, c'est membre référence ? Les membres
références sont normalement rarissime. (De même que les membres donnés
publiques, d'ailleurs, dans une class qui a aussi des membres privés.)
Budget(char * c, char *n, Currency v);
private:
string categorie;
string nom;
Currency valeur;
}
char * est indispensable pour des problèmes de portabilité, je
converti mon
AMA plutôt 'char const*' ? Sinon tu ne pourras pas passer des chaînes
constantes...
.......
Apparemment tu cherches
: ..., categorie(c, std::min(std::strlen(c), std::size_t(80)))
Voire simplement categorie( s ).
Ton 'c' vient d'où alors ? L'intérêt des std::string est justement de
ne pas être obligé de couper les chaînes à cause d'utilisation des
buffeurs de taille fixe ! Par contre, si 'c' est un pointeur invalide
(NULL, non initialisé ou pointant sur une zone de mémoire libérée),
effectivement ça se passera mal...
C'est vrai que quelques coups de string(c) avec un c où strlen(c) vaut
35478945231, ça pourrait poser des problèmes sur beaucoup de systèmes.
Du genre bad_alloc. D'ailleurs, l'existance même d'une chaîne (C ou
std::string) de cette taille est impossible sur pas mal des machines.
Si le poster a réelement à gerer des chaînes de cette longueur, il se
peut bien qu'il a besoin des moyens spéciaux.
On aimerait d'abord comprendre le problème.
Tu peux simplement appeler std::random_shuffle(it_begin, in_end) mais
ni le générateur de nombres aléatoires ni la façon d'initialiser son
seed sont spécifiés dans la Norme (§ 25.2.11). Si le résultat n'est
pas assez aléatoire pour toi, tu peux utiliser ton propre générateur
qui gère son seed. Exemple (il y en a d'autres sur le Web) :
....
Chez Boost, par exemple, où à ma site.
....
class Budget
{
public:
const string &category;
const string &name;
const Currency &value;
Pour commencer, c'est quoi, c'est membre référence ? Les membres
références sont normalement rarissime. (De même que les membres donnés
publiques, d'ailleurs, dans une class qui a aussi des membres privés.)
Budget(char * c, char *n, Currency v);
private:
string categorie;
string nom;
Currency valeur;
}char * est indispensable pour des problèmes de portabilité, je
converti monAMA plutôt 'char const*' ? Sinon tu ne pourras pas passer des chaînes
constantes...
.......Apparemment tu cherches
: ..., categorie(c, std::min(std::strlen(c), std::size_t(80)))
Voire simplement categorie( s ).
Ton 'c' vient d'où alors ? L'intérêt des std::string est justement de
ne pas être obligé de couper les chaînes à cause d'utilisation des
buffeurs de taille fixe ! Par contre, si 'c' est un pointeur invalide
(NULL, non initialisé ou pointant sur une zone de mémoire libérée),
effectivement ça se passera mal...
C'est vrai que quelques coups de string(c) avec un c où strlen(c) vaut
35478945231, ça pourrait poser des problèmes sur beaucoup de systèmes.
Du genre bad_alloc. D'ailleurs, l'existance même d'une chaîne (C ou
std::string) de cette taille est impossible sur pas mal des machines.
Si le poster a réelement à gerer des chaînes de cette longueur, il se
peut bien qu'il a besoin des moyens spéciaux.
On aimerait d'abord comprendre le problème.Tu peux simplement appeler std::random_shuffle(it_begin, in_end) mais
ni le générateur de nombres aléatoires ni la façon d'initialiser son
seed sont spécifiés dans la Norme (§ 25.2.11). Si le résultat n'est
pas assez aléatoire pour toi, tu peux utiliser ton propre générateur
qui gère son seed. Exemple (il y en a d'autres sur le Web) :
....
Chez Boost, par exemple, où à ma site.
....
le Wednesday 08 September 2004 10:26, écrivit :C'est vrai que quelques coups de string(c) avec un c où strlen(c)
vaut 35478945231, ça pourrait poser des problèmes sur beaucoup de
systèmes. Du genre bad_alloc. D'ailleurs, l'existance même d'une
chaîne (C ou std::string) de cette taille est impossible sur pas mal
des machines.
oui, et je trouve que "string(c)" est la bonne chose à faire.
Dans les milieux internationaux, 42 est la valeur préférée, mais les
allemands semblent préférer 4711.
ça m'intrigue, autant je connais 42, autant je ne vois pas du tout
d'où vient 4711...
Qu'est ce que c'est que ce nombre ??
le Wednesday 08 September 2004 10:26, kanze@gabi-soft.fr écrivit :
C'est vrai que quelques coups de string(c) avec un c où strlen(c)
vaut 35478945231, ça pourrait poser des problèmes sur beaucoup de
systèmes. Du genre bad_alloc. D'ailleurs, l'existance même d'une
chaîne (C ou std::string) de cette taille est impossible sur pas mal
des machines.
oui, et je trouve que "string(c)" est la bonne chose à faire.
Dans les milieux internationaux, 42 est la valeur préférée, mais les
allemands semblent préférer 4711.
ça m'intrigue, autant je connais 42, autant je ne vois pas du tout
d'où vient 4711...
Qu'est ce que c'est que ce nombre ??
le Wednesday 08 September 2004 10:26, écrivit :C'est vrai que quelques coups de string(c) avec un c où strlen(c)
vaut 35478945231, ça pourrait poser des problèmes sur beaucoup de
systèmes. Du genre bad_alloc. D'ailleurs, l'existance même d'une
chaîne (C ou std::string) de cette taille est impossible sur pas mal
des machines.
oui, et je trouve que "string(c)" est la bonne chose à faire.
Dans les milieux internationaux, 42 est la valeur préférée, mais les
allemands semblent préférer 4711.
ça m'intrigue, autant je connais 42, autant je ne vois pas du tout
d'où vient 4711...
Qu'est ce que c'est que ce nombre ??
class Budget
{
public:
const string &category;
const string &name;
const Currency &value;
Pour commencer, c'est quoi, c'est membre référence ? Les membres
références sont normalement rarissime. (De même que les membres
donnés publiques, d'ailleurs, dans une class qui a aussi des membres
privés.)
je ne me rappelle plus dans quel bouquin j'ai lu ça.
d'après ce que j'ai compris on peut faire :
class A
{
public:
int valeur();
void setValeur(int nlleValeur);
....
private:
int pValeur;
};
ou alors :
class A
{
public:
const int &valeur;
void setValeur(int nlleValeur);
...
private:
pValeur;
};
j'ai trouvé la solution de constante référence plus jolie et qui évite
une fonction et ainsi des bug en cas de printf à l'arrache pour
debugger vite fait donc j'ai gardé cette habitude. (mauvaise ou bonne
je ne sais pas, j'apprend !)
Budget(char * c, char *n, Currency v);
private:
string categorie;
string nom;
Currency valeur;
}
char * est indispensable pour des problèmes de portabilité, je
converti mon
AMA plutôt 'char const*' ? Sinon tu ne pourras pas passer des
chaînes constantes...
oui, je n'ai pas retranscrit les const, c'est pas du copier/coller, le
source (le début, j'avance pas depuis que j'essaye d'éviter Qt) est
sous linux, pas sous Windows et j'étais sous Windows........Apparemment tu cherches
: ..., categorie(c, std::min(std::strlen(c), std::size_t(80)))
Voire simplement categorie( s ).
du tout, enfin presque :
Budget est une pseudo-struct totalement en lecture seule. contenant
categorie, nom, valeur et d'autres champs. Elle est modifiable
uniquement via son "Id" via la classe contenant la collection des
budgets
begin{HorsSujet}
pour la petite histoire :
TCollection en BP7 sous dos lors de la première implémentation en 1993
TList sous Delphi en 1996
???? en Qt 2 (mon disque a explosé et j'ai tout perdu je me souviens
plus de de l'année)
QPtrList en Qt 3 depuis 2001
et sera list<Budget> en STL je penses... si j'y arrive !
end{HorsSujet}
Ce que je cherchais à faire, c'est tout simplement :
lors de la lecture du fichier contenant le budget, ou de l'import d'un
budget fabriqué à la main par l'utilisateur dans un fichier texte, le
constructeur se débrouille tout seul pour dégager les erreurs genre
nom trop longs ou si le fichier est corrompu ou si un rigolo (moi par
exemple :-)) lui balance un fichier totalement foireux comme une image
jpeg trafiquée à l'import, le système de vérification soit au plus
profond possible du coeur du système de gestion. Plus les objets
gèrent les erreurs, moins on a besoin de le gérer en amont. je me
trompe ?
Ton 'c' vient d'où alors ? L'intérêt des std::string est justement
de ne pas être obligé de couper les chaînes à cause d'utilisation
des buffeurs de taille fixe ! Par contre, si 'c' est un pointeur
invalide (NULL, non initialisé ou pointant sur une zone de mémoire
libérée), effectivement ça se passera mal...
comme dans le cas d'un fichier foireux genre disquette hs, je l'avais
oublié celui là. le prog que j'utilise pour faire mes comptes marche
pas trop mal et j'ai toujours mis un point d'honneur à ce que la place
tenue par les fichiers de données et les temps de traitements soit
minimaux.
begin{HorsSujet}
en delphi, 10 ans de compte tenaient largement sur une disquette
360Ko. Actuellement avec Qt, j'ai 4 ans de compte sur 80ko (pas de
compression) :-)
end{HorsSujet}C'est vrai que quelques coups de string(c) avec un c où strlen(c)
vaut 35478945231, ça pourrait poser des problèmes sur beaucoup de
systèmes. Du genre bad_alloc. D'ailleurs, l'existance même d'une
chaîne (C ou std::string) de cette taille est impossible sur pas mal
des machines.
Si le poster a réelement à gerer des chaînes de cette longueur, il
se peut bien qu'il a besoin des moyens spéciaux.
j'ai volontairement exagéré la taille pour montrer le problème :
impossible de contrôler la quantité d'octets copiés à la source
enfin presque, je vais pas vous/me casser plus la tête :
#include <cstring>
strncpy
comme ça le problème est réglé
j'espère que c'est plus clair : je ne veux pas copier des données
inutiles en mémoire pour rien, ne copier que le nécessaire et pas
plus.
string ne sait pas faire, cstring oui, tant pis j'utiliserai
strncpy. C'est pas beau mais au moins ça fait ce que je voulais sans
exceptions, sans copie inutile, simplement :
class MyString
{
MyString(char *source, long maxLen) {
while (source[i] && (i < MaxLen)) do {
data.append(source[i]);
++i;
}
}
}
(c'est du géronimo :-))
On aimerait d'abord comprendre le problème.Tu peux simplement appeler std::random_shuffle(it_begin, in_end)
mais ni le générateur de nombres aléatoires ni la façon
d'initialiser son seed sont spécifiés dans la Norme (§ 25.2.11). Si
le résultat n'est pas assez aléatoire pour toi, tu peux utiliser ton
propre générateur qui gère son seed. Exemple (il y en a d'autres sur
le Web) :
....
Chez Boost, par exemple, où à ma site.
....
pas assez aléatoire qu'il disait :-)
quand je suis tombé dessus, j'ai crié eurêka ! mes collègues en train
de manger à côté m'ont pris pour un dingue ! Le soir, j'ai implémenté
un mélangeur de nom de fichiers (genre celui qui permet d'avoir des
fonds d'écrans aléatoires sous Linux) en quelques lignes de code
seulement.
Puissant le C++ me suis-je dit... avant d'exécuter le programme
plusieurs fois de suite et de voir que random ne randome rien du tout,
la séquence étant toujours la même, tant pis. Il semble que
"fonctionnal" ai quelque chose là dessus mais j'ai pas encore lu.
ps: au fait, pourquoi la faq de fr.comp.lang.c++ ne propose que des
ouvrage en anglais et uniquement chez Addison Wesley ? :-)
class Budget
{
public:
const string &category;
const string &name;
const Currency &value;
Pour commencer, c'est quoi, c'est membre référence ? Les membres
références sont normalement rarissime. (De même que les membres
donnés publiques, d'ailleurs, dans une class qui a aussi des membres
privés.)
je ne me rappelle plus dans quel bouquin j'ai lu ça.
d'après ce que j'ai compris on peut faire :
class A
{
public:
int valeur();
void setValeur(int nlleValeur);
....
private:
int pValeur;
};
ou alors :
class A
{
public:
const int &valeur;
void setValeur(int nlleValeur);
...
private:
pValeur;
};
j'ai trouvé la solution de constante référence plus jolie et qui évite
une fonction et ainsi des bug en cas de printf à l'arrache pour
debugger vite fait donc j'ai gardé cette habitude. (mauvaise ou bonne
je ne sais pas, j'apprend !)
Budget(char * c, char *n, Currency v);
private:
string categorie;
string nom;
Currency valeur;
}
char * est indispensable pour des problèmes de portabilité, je
converti mon
AMA plutôt 'char const*' ? Sinon tu ne pourras pas passer des
chaînes constantes...
oui, je n'ai pas retranscrit les const, c'est pas du copier/coller, le
source (le début, j'avance pas depuis que j'essaye d'éviter Qt) est
sous linux, pas sous Windows et j'étais sous Windows.
.......
Apparemment tu cherches
: ..., categorie(c, std::min(std::strlen(c), std::size_t(80)))
Voire simplement categorie( s ).
du tout, enfin presque :
Budget est une pseudo-struct totalement en lecture seule. contenant
categorie, nom, valeur et d'autres champs. Elle est modifiable
uniquement via son "Id" via la classe contenant la collection des
budgets
begin{HorsSujet}
pour la petite histoire :
TCollection en BP7 sous dos lors de la première implémentation en 1993
TList sous Delphi en 1996
???? en Qt 2 (mon disque a explosé et j'ai tout perdu je me souviens
plus de de l'année)
QPtrList en Qt 3 depuis 2001
et sera list<Budget> en STL je penses... si j'y arrive !
end{HorsSujet}
Ce que je cherchais à faire, c'est tout simplement :
lors de la lecture du fichier contenant le budget, ou de l'import d'un
budget fabriqué à la main par l'utilisateur dans un fichier texte, le
constructeur se débrouille tout seul pour dégager les erreurs genre
nom trop longs ou si le fichier est corrompu ou si un rigolo (moi par
exemple :-)) lui balance un fichier totalement foireux comme une image
jpeg trafiquée à l'import, le système de vérification soit au plus
profond possible du coeur du système de gestion. Plus les objets
gèrent les erreurs, moins on a besoin de le gérer en amont. je me
trompe ?
Ton 'c' vient d'où alors ? L'intérêt des std::string est justement
de ne pas être obligé de couper les chaînes à cause d'utilisation
des buffeurs de taille fixe ! Par contre, si 'c' est un pointeur
invalide (NULL, non initialisé ou pointant sur une zone de mémoire
libérée), effectivement ça se passera mal...
comme dans le cas d'un fichier foireux genre disquette hs, je l'avais
oublié celui là. le prog que j'utilise pour faire mes comptes marche
pas trop mal et j'ai toujours mis un point d'honneur à ce que la place
tenue par les fichiers de données et les temps de traitements soit
minimaux.
begin{HorsSujet}
en delphi, 10 ans de compte tenaient largement sur une disquette
360Ko. Actuellement avec Qt, j'ai 4 ans de compte sur 80ko (pas de
compression) :-)
end{HorsSujet}
C'est vrai que quelques coups de string(c) avec un c où strlen(c)
vaut 35478945231, ça pourrait poser des problèmes sur beaucoup de
systèmes. Du genre bad_alloc. D'ailleurs, l'existance même d'une
chaîne (C ou std::string) de cette taille est impossible sur pas mal
des machines.
Si le poster a réelement à gerer des chaînes de cette longueur, il
se peut bien qu'il a besoin des moyens spéciaux.
j'ai volontairement exagéré la taille pour montrer le problème :
impossible de contrôler la quantité d'octets copiés à la source
enfin presque, je vais pas vous/me casser plus la tête :
#include <cstring>
strncpy
comme ça le problème est réglé
j'espère que c'est plus clair : je ne veux pas copier des données
inutiles en mémoire pour rien, ne copier que le nécessaire et pas
plus.
string ne sait pas faire, cstring oui, tant pis j'utiliserai
strncpy. C'est pas beau mais au moins ça fait ce que je voulais sans
exceptions, sans copie inutile, simplement :
class MyString
{
MyString(char *source, long maxLen) {
while (source[i] && (i < MaxLen)) do {
data.append(source[i]);
++i;
}
}
}
(c'est du géronimo :-))
On aimerait d'abord comprendre le problème.
Tu peux simplement appeler std::random_shuffle(it_begin, in_end)
mais ni le générateur de nombres aléatoires ni la façon
d'initialiser son seed sont spécifiés dans la Norme (§ 25.2.11). Si
le résultat n'est pas assez aléatoire pour toi, tu peux utiliser ton
propre générateur qui gère son seed. Exemple (il y en a d'autres sur
le Web) :
....
Chez Boost, par exemple, où à ma site.
....
pas assez aléatoire qu'il disait :-)
quand je suis tombé dessus, j'ai crié eurêka ! mes collègues en train
de manger à côté m'ont pris pour un dingue ! Le soir, j'ai implémenté
un mélangeur de nom de fichiers (genre celui qui permet d'avoir des
fonds d'écrans aléatoires sous Linux) en quelques lignes de code
seulement.
Puissant le C++ me suis-je dit... avant d'exécuter le programme
plusieurs fois de suite et de voir que random ne randome rien du tout,
la séquence étant toujours la même, tant pis. Il semble que
"fonctionnal" ai quelque chose là dessus mais j'ai pas encore lu.
ps: au fait, pourquoi la faq de fr.comp.lang.c++ ne propose que des
ouvrage en anglais et uniquement chez Addison Wesley ? :-)
class Budget
{
public:
const string &category;
const string &name;
const Currency &value;
Pour commencer, c'est quoi, c'est membre référence ? Les membres
références sont normalement rarissime. (De même que les membres
donnés publiques, d'ailleurs, dans une class qui a aussi des membres
privés.)
je ne me rappelle plus dans quel bouquin j'ai lu ça.
d'après ce que j'ai compris on peut faire :
class A
{
public:
int valeur();
void setValeur(int nlleValeur);
....
private:
int pValeur;
};
ou alors :
class A
{
public:
const int &valeur;
void setValeur(int nlleValeur);
...
private:
pValeur;
};
j'ai trouvé la solution de constante référence plus jolie et qui évite
une fonction et ainsi des bug en cas de printf à l'arrache pour
debugger vite fait donc j'ai gardé cette habitude. (mauvaise ou bonne
je ne sais pas, j'apprend !)
Budget(char * c, char *n, Currency v);
private:
string categorie;
string nom;
Currency valeur;
}
char * est indispensable pour des problèmes de portabilité, je
converti mon
AMA plutôt 'char const*' ? Sinon tu ne pourras pas passer des
chaînes constantes...
oui, je n'ai pas retranscrit les const, c'est pas du copier/coller, le
source (le début, j'avance pas depuis que j'essaye d'éviter Qt) est
sous linux, pas sous Windows et j'étais sous Windows........Apparemment tu cherches
: ..., categorie(c, std::min(std::strlen(c), std::size_t(80)))
Voire simplement categorie( s ).
du tout, enfin presque :
Budget est une pseudo-struct totalement en lecture seule. contenant
categorie, nom, valeur et d'autres champs. Elle est modifiable
uniquement via son "Id" via la classe contenant la collection des
budgets
begin{HorsSujet}
pour la petite histoire :
TCollection en BP7 sous dos lors de la première implémentation en 1993
TList sous Delphi en 1996
???? en Qt 2 (mon disque a explosé et j'ai tout perdu je me souviens
plus de de l'année)
QPtrList en Qt 3 depuis 2001
et sera list<Budget> en STL je penses... si j'y arrive !
end{HorsSujet}
Ce que je cherchais à faire, c'est tout simplement :
lors de la lecture du fichier contenant le budget, ou de l'import d'un
budget fabriqué à la main par l'utilisateur dans un fichier texte, le
constructeur se débrouille tout seul pour dégager les erreurs genre
nom trop longs ou si le fichier est corrompu ou si un rigolo (moi par
exemple :-)) lui balance un fichier totalement foireux comme une image
jpeg trafiquée à l'import, le système de vérification soit au plus
profond possible du coeur du système de gestion. Plus les objets
gèrent les erreurs, moins on a besoin de le gérer en amont. je me
trompe ?
Ton 'c' vient d'où alors ? L'intérêt des std::string est justement
de ne pas être obligé de couper les chaînes à cause d'utilisation
des buffeurs de taille fixe ! Par contre, si 'c' est un pointeur
invalide (NULL, non initialisé ou pointant sur une zone de mémoire
libérée), effectivement ça se passera mal...
comme dans le cas d'un fichier foireux genre disquette hs, je l'avais
oublié celui là. le prog que j'utilise pour faire mes comptes marche
pas trop mal et j'ai toujours mis un point d'honneur à ce que la place
tenue par les fichiers de données et les temps de traitements soit
minimaux.
begin{HorsSujet}
en delphi, 10 ans de compte tenaient largement sur une disquette
360Ko. Actuellement avec Qt, j'ai 4 ans de compte sur 80ko (pas de
compression) :-)
end{HorsSujet}C'est vrai que quelques coups de string(c) avec un c où strlen(c)
vaut 35478945231, ça pourrait poser des problèmes sur beaucoup de
systèmes. Du genre bad_alloc. D'ailleurs, l'existance même d'une
chaîne (C ou std::string) de cette taille est impossible sur pas mal
des machines.
Si le poster a réelement à gerer des chaînes de cette longueur, il
se peut bien qu'il a besoin des moyens spéciaux.
j'ai volontairement exagéré la taille pour montrer le problème :
impossible de contrôler la quantité d'octets copiés à la source
enfin presque, je vais pas vous/me casser plus la tête :
#include <cstring>
strncpy
comme ça le problème est réglé
j'espère que c'est plus clair : je ne veux pas copier des données
inutiles en mémoire pour rien, ne copier que le nécessaire et pas
plus.
string ne sait pas faire, cstring oui, tant pis j'utiliserai
strncpy. C'est pas beau mais au moins ça fait ce que je voulais sans
exceptions, sans copie inutile, simplement :
class MyString
{
MyString(char *source, long maxLen) {
while (source[i] && (i < MaxLen)) do {
data.append(source[i]);
++i;
}
}
}
(c'est du géronimo :-))
On aimerait d'abord comprendre le problème.Tu peux simplement appeler std::random_shuffle(it_begin, in_end)
mais ni le générateur de nombres aléatoires ni la façon
d'initialiser son seed sont spécifiés dans la Norme (§ 25.2.11). Si
le résultat n'est pas assez aléatoire pour toi, tu peux utiliser ton
propre générateur qui gère son seed. Exemple (il y en a d'autres sur
le Web) :
....
Chez Boost, par exemple, où à ma site.
....
pas assez aléatoire qu'il disait :-)
quand je suis tombé dessus, j'ai crié eurêka ! mes collègues en train
de manger à côté m'ont pris pour un dingue ! Le soir, j'ai implémenté
un mélangeur de nom de fichiers (genre celui qui permet d'avoir des
fonds d'écrans aléatoires sous Linux) en quelques lignes de code
seulement.
Puissant le C++ me suis-je dit... avant d'exécuter le programme
plusieurs fois de suite et de voir que random ne randome rien du tout,
la séquence étant toujours la même, tant pis. Il semble que
"fonctionnal" ai quelque chose là dessus mais j'ai pas encore lu.
ps: au fait, pourquoi la faq de fr.comp.lang.c++ ne propose que des
ouvrage en anglais et uniquement chez Addison Wesley ? :-)
Samuel Krempp wrote in message
news:<413f4a01$0$7592$...le Wednesday 08 September 2004 10:26, écrivit :oui, et je trouve que "string(c)" est la bonne chose à faire.
Tout à fait. Ce que je soupçonne, c'est que la longueur qu'il impose,
c'est parce que dans la version C, il avait des char[] de longueur fixe,
et que ce ne fait pas partie de la spécification externe. Donc, c'est
string(c), et on se libère du contraint de la longueur. Si la longueur
fasse réelement partie des contraints externes (parfois le cas dans les
protocols de transmission, par exemple), c'est assez facile à tronquer
par la suite.
[...]
--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Samuel Krempp <krempp@crans.truc.en.trop.ens-cachan.fr> wrote in message
news:<413f4a01$0$7592$636a15ce@news.free.fr>...
le Wednesday 08 September 2004 10:26, kanze@gabi-soft.fr écrivit :
oui, et je trouve que "string(c)" est la bonne chose à faire.
Tout à fait. Ce que je soupçonne, c'est que la longueur qu'il impose,
c'est parce que dans la version C, il avait des char[] de longueur fixe,
et que ce ne fait pas partie de la spécification externe. Donc, c'est
string(c), et on se libère du contraint de la longueur. Si la longueur
fasse réelement partie des contraints externes (parfois le cas dans les
protocols de transmission, par exemple), c'est assez facile à tronquer
par la suite.
[...]
--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Samuel Krempp wrote in message
news:<413f4a01$0$7592$...le Wednesday 08 September 2004 10:26, écrivit :oui, et je trouve que "string(c)" est la bonne chose à faire.
Tout à fait. Ce que je soupçonne, c'est que la longueur qu'il impose,
c'est parce que dans la version C, il avait des char[] de longueur fixe,
et que ce ne fait pas partie de la spécification externe. Donc, c'est
string(c), et on se libère du contraint de la longueur. Si la longueur
fasse réelement partie des contraints externes (parfois le cas dans les
protocols de transmission, par exemple), c'est assez facile à tronquer
par la suite.
[...]
--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
....
Je ne l'ai jamais vu avant. De tête, comme ça, en revanche, je vois deux
choses qui pourraient être des désavantages dans certains cas : avec
toutes les implémentations que je connais, on augmente la taille de
l'objet -- quand les types référencés sont simple, comme int, on peut
facilement la doubler, et on interdit l'affectation. Selon les
compilateurs, c'est aussi fort possible que l'accès en soit moins rapide
qu'avec une fonction inline.
.....
--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
....
Je ne l'ai jamais vu avant. De tête, comme ça, en revanche, je vois deux
choses qui pourraient être des désavantages dans certains cas : avec
toutes les implémentations que je connais, on augmente la taille de
l'objet -- quand les types référencés sont simple, comme int, on peut
facilement la doubler, et on interdit l'affectation. Selon les
compilateurs, c'est aussi fort possible que l'accès en soit moins rapide
qu'avec une fonction inline.
.....
--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
....
Je ne l'ai jamais vu avant. De tête, comme ça, en revanche, je vois deux
choses qui pourraient être des désavantages dans certains cas : avec
toutes les implémentations que je connais, on augmente la taille de
l'objet -- quand les types référencés sont simple, comme int, on peut
facilement la doubler, et on interdit l'affectation. Selon les
compilateurs, c'est aussi fort possible que l'accès en soit moins rapide
qu'avec une fonction inline.
.....
--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
toujours sur la conception de la classe Budget ...
voilà mon nouveau problème, j'espère ne pas me planter en tapant, j'ai
pas gardé le code de test (oui je sais... :-))
// class collection;
/* classe contenant des A et fournissant des services
* genre des parsers d'importation ;-) et contenant
* une list<A>
*/
// A ne doit être accessible qu'en lecture seule en direct
// et en lecture/écriture par collection.
// (pour les champs d'une listview qt par exemple)
les champs imortant sont 2 string (categorie et nom) qui servent pour
les comparaisons. (et uniquement ça, le stockage sur disque se fait
par l'id du budget, beauuuuucoup plus petit)
je veux définir les operateur <, = et ==. pour < et =, pas de problème
par contre pour == c'est une autre histoire :
// deux choix, choix n° 1
class A {
// friend class collections;
friend operator==(const A&, const A&);
public:
A(nv) : pv(v) { } ;
int v() { return pv; };
private:
int pv;
};
bool operator ==(const A&a1, const A&a2)
{
return (a1.pv == a2.pv)
};
// et choix n°2
class A {
// friend class collection;
public:
const int &v;
A(int nv);
private:
int pv;
}
bool operator ==(const A&a1, const A& a2)
{
return (a1.v == a2.v)
}
voilà pourquoi j'avais pris l'habitude d'utiliser les réf constantes,
pour virer les "friend operator" que j'avais pas 1/2 tonnes sur
d'autres classes (les opérateur + - / = < > >= <= == != <<)
y'a t-il une implémentation qui permette d'utiliser les fonction
inline mais sans les friend operator à chaque fois ??
j'avais bêtement essayé :
a1.v() == a2.v() mais les compilos me le refusent parce que
a1 et a2 sont constants ...
toujours sur la conception de la classe Budget ...
voilà mon nouveau problème, j'espère ne pas me planter en tapant, j'ai
pas gardé le code de test (oui je sais... :-))
// class collection;
/* classe contenant des A et fournissant des services
* genre des parsers d'importation ;-) et contenant
* une list<A>
*/
// A ne doit être accessible qu'en lecture seule en direct
// et en lecture/écriture par collection.
// (pour les champs d'une listview qt par exemple)
les champs imortant sont 2 string (categorie et nom) qui servent pour
les comparaisons. (et uniquement ça, le stockage sur disque se fait
par l'id du budget, beauuuuucoup plus petit)
je veux définir les operateur <, = et ==. pour < et =, pas de problème
par contre pour == c'est une autre histoire :
// deux choix, choix n° 1
class A {
// friend class collections;
friend operator==(const A&, const A&);
public:
A(nv) : pv(v) { } ;
int v() { return pv; };
private:
int pv;
};
bool operator ==(const A&a1, const A&a2)
{
return (a1.pv == a2.pv)
};
// et choix n°2
class A {
// friend class collection;
public:
const int &v;
A(int nv);
private:
int pv;
}
bool operator ==(const A&a1, const A& a2)
{
return (a1.v == a2.v)
}
voilà pourquoi j'avais pris l'habitude d'utiliser les réf constantes,
pour virer les "friend operator" que j'avais pas 1/2 tonnes sur
d'autres classes (les opérateur + - / = < > >= <= == != <<)
y'a t-il une implémentation qui permette d'utiliser les fonction
inline mais sans les friend operator à chaque fois ??
j'avais bêtement essayé :
a1.v() == a2.v() mais les compilos me le refusent parce que
a1 et a2 sont constants ...
toujours sur la conception de la classe Budget ...
voilà mon nouveau problème, j'espère ne pas me planter en tapant, j'ai
pas gardé le code de test (oui je sais... :-))
// class collection;
/* classe contenant des A et fournissant des services
* genre des parsers d'importation ;-) et contenant
* une list<A>
*/
// A ne doit être accessible qu'en lecture seule en direct
// et en lecture/écriture par collection.
// (pour les champs d'une listview qt par exemple)
les champs imortant sont 2 string (categorie et nom) qui servent pour
les comparaisons. (et uniquement ça, le stockage sur disque se fait
par l'id du budget, beauuuuucoup plus petit)
je veux définir les operateur <, = et ==. pour < et =, pas de problème
par contre pour == c'est une autre histoire :
// deux choix, choix n° 1
class A {
// friend class collections;
friend operator==(const A&, const A&);
public:
A(nv) : pv(v) { } ;
int v() { return pv; };
private:
int pv;
};
bool operator ==(const A&a1, const A&a2)
{
return (a1.pv == a2.pv)
};
// et choix n°2
class A {
// friend class collection;
public:
const int &v;
A(int nv);
private:
int pv;
}
bool operator ==(const A&a1, const A& a2)
{
return (a1.v == a2.v)
}
voilà pourquoi j'avais pris l'habitude d'utiliser les réf constantes,
pour virer les "friend operator" que j'avais pas 1/2 tonnes sur
d'autres classes (les opérateur + - / = < > >= <= == != <<)
y'a t-il une implémentation qui permette d'utiliser les fonction
inline mais sans les friend operator à chaque fois ??
j'avais bêtement essayé :
a1.v() == a2.v() mais les compilos me le refusent parce que
a1 et a2 sont constants ...
Ceci dit, étant donné les rapports entre les différents
opérateurs de comparaison, il m'arrive souvent d'implémenter
une fonction :
int
A::compare( A const& other ) const
{
// renvoie -1, 0 ou 1, selon que *this est
// <, == ou > à other.
}
C'est une fonction membre, donc avec accès à toutes les
attributes.
Ensuite, j'ai simplement :
inline bool
operator==( A const& lhs, A const& rhs )
{
return lhs.compare( rhs ) == 0 ;
}
[...]
À vrai dire, je fais ça tellement souvent, je me démande si ça
ne vaut pas la peine d'en définir des macros :
#define declareOneCmpOp( Type, op )
inline bool
operator op ( Type const& lhs, Type const& rhs )
{
return lhs.compare( rhs ) op 0 ;
}
Ceci dit, étant donné les rapports entre les différents
opérateurs de comparaison, il m'arrive souvent d'implémenter
une fonction :
int
A::compare( A const& other ) const
{
// renvoie -1, 0 ou 1, selon que *this est
// <, == ou > à other.
}
C'est une fonction membre, donc avec accès à toutes les
attributes.
Ensuite, j'ai simplement :
inline bool
operator==( A const& lhs, A const& rhs )
{
return lhs.compare( rhs ) == 0 ;
}
[...]
À vrai dire, je fais ça tellement souvent, je me démande si ça
ne vaut pas la peine d'en définir des macros :
#define declareOneCmpOp( Type, op )
inline bool
operator op ( Type const& lhs, Type const& rhs )
{
return lhs.compare( rhs ) op 0 ;
}
Ceci dit, étant donné les rapports entre les différents
opérateurs de comparaison, il m'arrive souvent d'implémenter
une fonction :
int
A::compare( A const& other ) const
{
// renvoie -1, 0 ou 1, selon que *this est
// <, == ou > à other.
}
C'est une fonction membre, donc avec accès à toutes les
attributes.
Ensuite, j'ai simplement :
inline bool
operator==( A const& lhs, A const& rhs )
{
return lhs.compare( rhs ) == 0 ;
}
[...]
À vrai dire, je fais ça tellement souvent, je me démande si ça
ne vaut pas la peine d'en définir des macros :
#define declareOneCmpOp( Type, op )
inline bool
operator op ( Type const& lhs, Type const& rhs )
{
return lhs.compare( rhs ) op 0 ;
}
class A : public Comparaisons<A> // CRTP ou B&N trick
{
public :
int Compare(const A& p_v) const
{
return ...;
}
//...
};
A a1, a2, a3;
if (a1 < a2 || a2 == a3) ...
Il faut simplement avoir ceci quelque part :
template <typename T>
class Comparaisons
{
public :
friend bool operator==(const T& p_gauche, const T& p_droit)
{ return p_gauche.Compare(p_droit) == 0; }
friend bool operator!=(const T& p_gauche, const T& p_droit)
{ return p_gauche.Compare(p_droit) != 0; }
friend bool operator<=(const T& p_gauche, const T& p_droit)
{ return p_gauche.Compare(p_droit) <= 0; }
friend bool operator>=(const T& p_gauche, const T& p_droit)
{ return p_gauche.Compare(p_droit) >= 0; }
friend bool operator<(const T& p_gauche, const T& p_droit)
{ return p_gauche.Compare(p_droit) < 0; }
friend bool operator>(const T& p_gauche, const T& p_droit)
{ return p_gauche.Compare(p_droit) > 0; }
};
class A : public Comparaisons<A> // CRTP ou B&N trick
{
public :
int Compare(const A& p_v) const
{
return ...;
}
//...
};
A a1, a2, a3;
if (a1 < a2 || a2 == a3) ...
Il faut simplement avoir ceci quelque part :
template <typename T>
class Comparaisons
{
public :
friend bool operator==(const T& p_gauche, const T& p_droit)
{ return p_gauche.Compare(p_droit) == 0; }
friend bool operator!=(const T& p_gauche, const T& p_droit)
{ return p_gauche.Compare(p_droit) != 0; }
friend bool operator<=(const T& p_gauche, const T& p_droit)
{ return p_gauche.Compare(p_droit) <= 0; }
friend bool operator>=(const T& p_gauche, const T& p_droit)
{ return p_gauche.Compare(p_droit) >= 0; }
friend bool operator<(const T& p_gauche, const T& p_droit)
{ return p_gauche.Compare(p_droit) < 0; }
friend bool operator>(const T& p_gauche, const T& p_droit)
{ return p_gauche.Compare(p_droit) > 0; }
};
class A : public Comparaisons<A> // CRTP ou B&N trick
{
public :
int Compare(const A& p_v) const
{
return ...;
}
//...
};
A a1, a2, a3;
if (a1 < a2 || a2 == a3) ...
Il faut simplement avoir ceci quelque part :
template <typename T>
class Comparaisons
{
public :
friend bool operator==(const T& p_gauche, const T& p_droit)
{ return p_gauche.Compare(p_droit) == 0; }
friend bool operator!=(const T& p_gauche, const T& p_droit)
{ return p_gauche.Compare(p_droit) != 0; }
friend bool operator<=(const T& p_gauche, const T& p_droit)
{ return p_gauche.Compare(p_droit) <= 0; }
friend bool operator>=(const T& p_gauche, const T& p_droit)
{ return p_gauche.Compare(p_droit) >= 0; }
friend bool operator<(const T& p_gauche, const T& p_droit)
{ return p_gauche.Compare(p_droit) < 0; }
friend bool operator>(const T& p_gauche, const T& p_droit)
{ return p_gauche.Compare(p_droit) > 0; }
};
Dans news:,Ceci dit, étant donné les rapports entre les différents
opérateurs de comparaison, il m'arrive souvent d'implémenter
une fonction :
int
A::compare( A const& other ) const
{
// renvoie -1, 0 ou 1, selon que *this est
// <, == ou > à other.
}
C'est une fonction membre, donc avec accès à toutes les
attributes.
Ensuite, j'ai simplement :
inline bool
operator==( A const& lhs, A const& rhs )
{
return lhs.compare( rhs ) == 0 ;
}
[...]À vrai dire, je fais ça tellement souvent, je me démande si ça
ne vaut pas la peine d'en définir des macros :
#define declareOneCmpOp( Type, op )
inline bool
operator op ( Type const& lhs, Type const& rhs )
{
return lhs.compare( rhs ) op 0 ;
}
Toi qui est amateur de Barton et Nackman, je suis surpris que tu
penses à une macro et que tu ne penses pas plutôt à faire ceci :
class A : public Comparaisons<A> // CRTP ou B&N trick
Dans news:d6652001.0409132249.6b985b6c@posting.google.com,
Ceci dit, étant donné les rapports entre les différents
opérateurs de comparaison, il m'arrive souvent d'implémenter
une fonction :
int
A::compare( A const& other ) const
{
// renvoie -1, 0 ou 1, selon que *this est
// <, == ou > à other.
}
C'est une fonction membre, donc avec accès à toutes les
attributes.
Ensuite, j'ai simplement :
inline bool
operator==( A const& lhs, A const& rhs )
{
return lhs.compare( rhs ) == 0 ;
}
[...]
À vrai dire, je fais ça tellement souvent, je me démande si ça
ne vaut pas la peine d'en définir des macros :
#define declareOneCmpOp( Type, op )
inline bool
operator op ( Type const& lhs, Type const& rhs )
{
return lhs.compare( rhs ) op 0 ;
}
Toi qui est amateur de Barton et Nackman, je suis surpris que tu
penses à une macro et que tu ne penses pas plutôt à faire ceci :
class A : public Comparaisons<A> // CRTP ou B&N trick
Dans news:,Ceci dit, étant donné les rapports entre les différents
opérateurs de comparaison, il m'arrive souvent d'implémenter
une fonction :
int
A::compare( A const& other ) const
{
// renvoie -1, 0 ou 1, selon que *this est
// <, == ou > à other.
}
C'est une fonction membre, donc avec accès à toutes les
attributes.
Ensuite, j'ai simplement :
inline bool
operator==( A const& lhs, A const& rhs )
{
return lhs.compare( rhs ) == 0 ;
}
[...]À vrai dire, je fais ça tellement souvent, je me démande si ça
ne vaut pas la peine d'en définir des macros :
#define declareOneCmpOp( Type, op )
inline bool
operator op ( Type const& lhs, Type const& rhs )
{
return lhs.compare( rhs ) op 0 ;
}
Toi qui est amateur de Barton et Nackman, je suis surpris que tu
penses à une macro et que tu ne penses pas plutôt à faire ceci :
class A : public Comparaisons<A> // CRTP ou B&N trick