------------Kanze------------
class Vec
------------Kanze------------
class Vec
------------Kanze------------
class Vec
------------Kanze------------
class Vec
{
private:
float v[3] ;
public:
float x() const { return v[0] ; }
float y() const { return v[1] ; }
float z() const { return v[2] ; }
// ...
} ;
<< ------------Kanze------------
Tu préfères ça à une définition de float x,y,z et d'operator[] ?
------------Kanze------------
class Vec
{
private:
float v[3] ;
public:
float x() const { return v[0] ; }
float y() const { return v[1] ; }
float z() const { return v[2] ; }
// ...
} ;
<< ------------Kanze------------
Tu préfères ça à une définition de float x,y,z et d'operator[] ?
------------Kanze------------
class Vec
{
private:
float v[3] ;
public:
float x() const { return v[0] ; }
float y() const { return v[1] ; }
float z() const { return v[2] ; }
// ...
} ;
<< ------------Kanze------------
Tu préfères ça à une définition de float x,y,z et d'operator[] ?
Parce que ça multiplie la taille effective de la classe par 2 ou
3 ?
Potentiellement, aussi (selon le compilateur) ça peut
rallentir les accès d'une façon significative. Si on veut
donner les noms x, y et z (ce qui me semble utile, même dans
l'interface publique), la façon la plus simple, c'est des
fonctions inline :
class Vec
{
private:
float v[3] ;
public:
float x() const { return v[0] ; }
float y() const { return v[1] ; }
float z() const { return v[2] ; }
// ...
} ;
Parce que ça multiplie la taille effective de la classe par 2 ou
3 ?
Potentiellement, aussi (selon le compilateur) ça peut
rallentir les accès d'une façon significative. Si on veut
donner les noms x, y et z (ce qui me semble utile, même dans
l'interface publique), la façon la plus simple, c'est des
fonctions inline :
class Vec
{
private:
float v[3] ;
public:
float x() const { return v[0] ; }
float y() const { return v[1] ; }
float z() const { return v[2] ; }
// ...
} ;
Parce que ça multiplie la taille effective de la classe par 2 ou
3 ?
Potentiellement, aussi (selon le compilateur) ça peut
rallentir les accès d'une façon significative. Si on veut
donner les noms x, y et z (ce qui me semble utile, même dans
l'interface publique), la façon la plus simple, c'est des
fonctions inline :
class Vec
{
private:
float v[3] ;
public:
float x() const { return v[0] ; }
float y() const { return v[1] ; }
float z() const { return v[2] ; }
// ...
} ;
À ma décharge, je n'avais pas pensé aux problème
d'alignement, ça fonctionnait en pratique, et ça permettait
un accès direct à x, y et z que je trouvais plus rapide et
concis que v[0], v[1], v[2], ce qui a de l'importance pour
une telle classe de base.
si l'essentiel des opérations sont faites par des fonctions
membres de la classe Vec, il sera intéressant en effet de
garder que x,y,z afin d'éviter l'indexage dans ces traitements
internes.
Pourquoi ? En général, je trouve assez normal que les fonctions
membre aient à faire avec la représentation interne de la
classe.
pourquoi ne pas garder les deux, simplement redéfini selon:
Parce que ça multiplie la taille effective de la classe par 2 ou 3
Potentiellement, aussi (selon le compilateur) ça peut
ralentir les accès d'une façon significative.
Si on veut donner les noms x, y et z (ce qui me semble utile,
même dans l'interface publique), la façon la plus simple,
c'est des fonctions inline :
float x() const { return v[0] ; }
Dans certaines applications, je verrais bien une petite classe
qui ne faisait que ça -- définissait un tableau de trois
éléments, en permettant l'accès aussi bien comme celui d'un
tableau que par les noms x, y et z.
À ma décharge, je n'avais pas pensé aux problème
d'alignement, ça fonctionnait en pratique, et ça permettait
un accès direct à x, y et z que je trouvais plus rapide et
concis que v[0], v[1], v[2], ce qui a de l'importance pour
une telle classe de base.
si l'essentiel des opérations sont faites par des fonctions
membres de la classe Vec, il sera intéressant en effet de
garder que x,y,z afin d'éviter l'indexage dans ces traitements
internes.
Pourquoi ? En général, je trouve assez normal que les fonctions
membre aient à faire avec la représentation interne de la
classe.
pourquoi ne pas garder les deux, simplement redéfini selon:
Parce que ça multiplie la taille effective de la classe par 2 ou 3
Potentiellement, aussi (selon le compilateur) ça peut
ralentir les accès d'une façon significative.
Si on veut donner les noms x, y et z (ce qui me semble utile,
même dans l'interface publique), la façon la plus simple,
c'est des fonctions inline :
float x() const { return v[0] ; }
Dans certaines applications, je verrais bien une petite classe
qui ne faisait que ça -- définissait un tableau de trois
éléments, en permettant l'accès aussi bien comme celui d'un
tableau que par les noms x, y et z.
À ma décharge, je n'avais pas pensé aux problème
d'alignement, ça fonctionnait en pratique, et ça permettait
un accès direct à x, y et z que je trouvais plus rapide et
concis que v[0], v[1], v[2], ce qui a de l'importance pour
une telle classe de base.
si l'essentiel des opérations sont faites par des fonctions
membres de la classe Vec, il sera intéressant en effet de
garder que x,y,z afin d'éviter l'indexage dans ces traitements
internes.
Pourquoi ? En général, je trouve assez normal que les fonctions
membre aient à faire avec la représentation interne de la
classe.
pourquoi ne pas garder les deux, simplement redéfini selon:
Parce que ça multiplie la taille effective de la classe par 2 ou 3
Potentiellement, aussi (selon le compilateur) ça peut
ralentir les accès d'une façon significative.
Si on veut donner les noms x, y et z (ce qui me semble utile,
même dans l'interface publique), la façon la plus simple,
c'est des fonctions inline :
float x() const { return v[0] ; }
Dans certaines applications, je verrais bien une petite classe
qui ne faisait que ça -- définissait un tableau de trois
éléments, en permettant l'accès aussi bien comme celui d'un
tableau que par les noms x, y et z.
kanze wrote on 30/05/2006 08:51:À ma décharge, je n'avais pas pensé aux problème
d'alignement, ça fonctionnait en pratique, et ça permettait
un accès direct à x, y et z que je trouvais plus rapide et
concis que v[0], v[1], v[2], ce qui a de l'importance pour
une telle classe de base.
si l'essentiel des opérations sont faites par des fonctions
membres de la classe Vec, il sera intéressant en effet de
garder que x,y,z afin d'éviter l'indexage dans ces traitements
internes.
Pourquoi ? En général, je trouve assez normal que les fonctions
membre aient à faire avec la représentation interne de la
classe.
pardon ? veux-tu dire les fonctions membres de Vec ont le
droit d'utiliser x, y, z ? il ne semble pas que quiconque ait
dit le contraire ici.
mais peut-être préconises-tu que les fonctions membres
n'utilisent surtout pas les variables x, y et x mais des
getU/setU ou je ne sais quelle indirection au nom d'une
représentation interne.
pourquoi ne pas garder les deux, simplement redéfini selon:
Parce que ça multiplie la taille effective de la classe par
2 ou 3
oui et ?
Potentiellement, aussi (selon le compilateur) ça peut
ralentir les accès d'une façon significative.
ah oui ? tu peux détailler ce que "ça" recouvre ? (qu'est ce
qui ralentirait quoi ?)
selon mon humble avis, un accès à v[i] est résolu en qlq chose
comme un accès à l'adresse @instance + offset constant et donc
se traduit par des chargement immédiat où la notion de calcul
d'index a disparu. un accès à 'x' (où x est visiblement une
référence, factuellement un pointeur) devra charger une
adresse à @instance + offset constant puis utiliser le contenu
de cette adresse (un MOV en plus sur Intel, si c'est àa le
"significatif").
Si on veut donner les noms x, y et z (ce qui me semble utile,
même dans l'interface publique), la façon la plus simple,
c'est des fonctions inline :
float x() const { return v[0] ; }
je crois que l'on ne veut /pas/ de telles fonctions.
l'interface publique présentée montre clairement que
l'utilisation du "contenu" de la classe Vec se fait par un
accès à un float* (float[3]), d'où la fonction de cast
implicite.
je pense de plus que la présence des 'x', 'y' et 'z' n'est
justifiée que par le souhait /dans l'implémentation de cette
classe/ de ne pas utiliser un tableau indéxé - même si comme
dit plus haut cela n'induit aucun cout au runtime (offset
fixe) - car il est moins agréable de taper et relire des
v[0/1/2] que des x, y ou z.
la réponse la moins gélatineuse face à cela serait:
dans .h
private float v[3];
dans .cpp
#define x v[0]
#define y v[1]
#define z v[2]
Dans certaines applications, je verrais bien une petite classe
qui ne faisait que ça -- définissait un tableau de trois
éléments, en permettant l'accès aussi bien comme celui d'un
tableau que par les noms x, y et z.
x, y, z ne sont pas des noms mais des fonctions, un accès nommé serai t:
float{&} operator[] (char name) const {
if (name == 'x')
return v[0];
etc
}
qui serait insolvable s'il coexiste avec
operator const float*() const {
return v;
}
kanze wrote on 30/05/2006 08:51:
À ma décharge, je n'avais pas pensé aux problème
d'alignement, ça fonctionnait en pratique, et ça permettait
un accès direct à x, y et z que je trouvais plus rapide et
concis que v[0], v[1], v[2], ce qui a de l'importance pour
une telle classe de base.
si l'essentiel des opérations sont faites par des fonctions
membres de la classe Vec, il sera intéressant en effet de
garder que x,y,z afin d'éviter l'indexage dans ces traitements
internes.
Pourquoi ? En général, je trouve assez normal que les fonctions
membre aient à faire avec la représentation interne de la
classe.
pardon ? veux-tu dire les fonctions membres de Vec ont le
droit d'utiliser x, y, z ? il ne semble pas que quiconque ait
dit le contraire ici.
mais peut-être préconises-tu que les fonctions membres
n'utilisent surtout pas les variables x, y et x mais des
getU/setU ou je ne sais quelle indirection au nom d'une
représentation interne.
pourquoi ne pas garder les deux, simplement redéfini selon:
Parce que ça multiplie la taille effective de la classe par
2 ou 3
oui et ?
Potentiellement, aussi (selon le compilateur) ça peut
ralentir les accès d'une façon significative.
ah oui ? tu peux détailler ce que "ça" recouvre ? (qu'est ce
qui ralentirait quoi ?)
selon mon humble avis, un accès à v[i] est résolu en qlq chose
comme un accès à l'adresse @instance + offset constant et donc
se traduit par des chargement immédiat où la notion de calcul
d'index a disparu. un accès à 'x' (où x est visiblement une
référence, factuellement un pointeur) devra charger une
adresse à @instance + offset constant puis utiliser le contenu
de cette adresse (un MOV en plus sur Intel, si c'est àa le
"significatif").
Si on veut donner les noms x, y et z (ce qui me semble utile,
même dans l'interface publique), la façon la plus simple,
c'est des fonctions inline :
float x() const { return v[0] ; }
je crois que l'on ne veut /pas/ de telles fonctions.
l'interface publique présentée montre clairement que
l'utilisation du "contenu" de la classe Vec se fait par un
accès à un float* (float[3]), d'où la fonction de cast
implicite.
je pense de plus que la présence des 'x', 'y' et 'z' n'est
justifiée que par le souhait /dans l'implémentation de cette
classe/ de ne pas utiliser un tableau indéxé - même si comme
dit plus haut cela n'induit aucun cout au runtime (offset
fixe) - car il est moins agréable de taper et relire des
v[0/1/2] que des x, y ou z.
la réponse la moins gélatineuse face à cela serait:
dans .h
private float v[3];
dans .cpp
#define x v[0]
#define y v[1]
#define z v[2]
Dans certaines applications, je verrais bien une petite classe
qui ne faisait que ça -- définissait un tableau de trois
éléments, en permettant l'accès aussi bien comme celui d'un
tableau que par les noms x, y et z.
x, y, z ne sont pas des noms mais des fonctions, un accès nommé serai t:
float{&} operator[] (char name) const {
if (name == 'x')
return v[0];
etc
}
qui serait insolvable s'il coexiste avec
operator const float*() const {
return v;
}
kanze wrote on 30/05/2006 08:51:À ma décharge, je n'avais pas pensé aux problème
d'alignement, ça fonctionnait en pratique, et ça permettait
un accès direct à x, y et z que je trouvais plus rapide et
concis que v[0], v[1], v[2], ce qui a de l'importance pour
une telle classe de base.
si l'essentiel des opérations sont faites par des fonctions
membres de la classe Vec, il sera intéressant en effet de
garder que x,y,z afin d'éviter l'indexage dans ces traitements
internes.
Pourquoi ? En général, je trouve assez normal que les fonctions
membre aient à faire avec la représentation interne de la
classe.
pardon ? veux-tu dire les fonctions membres de Vec ont le
droit d'utiliser x, y, z ? il ne semble pas que quiconque ait
dit le contraire ici.
mais peut-être préconises-tu que les fonctions membres
n'utilisent surtout pas les variables x, y et x mais des
getU/setU ou je ne sais quelle indirection au nom d'une
représentation interne.
pourquoi ne pas garder les deux, simplement redéfini selon:
Parce que ça multiplie la taille effective de la classe par
2 ou 3
oui et ?
Potentiellement, aussi (selon le compilateur) ça peut
ralentir les accès d'une façon significative.
ah oui ? tu peux détailler ce que "ça" recouvre ? (qu'est ce
qui ralentirait quoi ?)
selon mon humble avis, un accès à v[i] est résolu en qlq chose
comme un accès à l'adresse @instance + offset constant et donc
se traduit par des chargement immédiat où la notion de calcul
d'index a disparu. un accès à 'x' (où x est visiblement une
référence, factuellement un pointeur) devra charger une
adresse à @instance + offset constant puis utiliser le contenu
de cette adresse (un MOV en plus sur Intel, si c'est àa le
"significatif").
Si on veut donner les noms x, y et z (ce qui me semble utile,
même dans l'interface publique), la façon la plus simple,
c'est des fonctions inline :
float x() const { return v[0] ; }
je crois que l'on ne veut /pas/ de telles fonctions.
l'interface publique présentée montre clairement que
l'utilisation du "contenu" de la classe Vec se fait par un
accès à un float* (float[3]), d'où la fonction de cast
implicite.
je pense de plus que la présence des 'x', 'y' et 'z' n'est
justifiée que par le souhait /dans l'implémentation de cette
classe/ de ne pas utiliser un tableau indéxé - même si comme
dit plus haut cela n'induit aucun cout au runtime (offset
fixe) - car il est moins agréable de taper et relire des
v[0/1/2] que des x, y ou z.
la réponse la moins gélatineuse face à cela serait:
dans .h
private float v[3];
dans .cpp
#define x v[0]
#define y v[1]
#define z v[2]
Dans certaines applications, je verrais bien une petite classe
qui ne faisait que ça -- définissait un tableau de trois
éléments, en permettant l'accès aussi bien comme celui d'un
tableau que par les noms x, y et z.
x, y, z ne sont pas des noms mais des fonctions, un accès nommé serai t:
float{&} operator[] (char name) const {
if (name == 'x')
return v[0];
etc
}
qui serait insolvable s'il coexiste avec
operator const float*() const {
return v;
}
float x() const { return v[0] ; }
je crois que l'on ne veut /pas/ de telles fonctions.
Pourquoi ?
Certes, mais le rôle des fonctions membres n'est-il pas
précisement de s'occuper de la représentation interne. Ou est-ce
que tu le trouves normal que la classe reserve l'interface
«@agréable » pour elle-même, et force les utilisateurs
d'utiliser celle moins agréable.
float{&} operator[] (char name) const {
if (name == 'x')
return v[0];
etc
}
Tu n'est pas sérieux, j'espère.
qui serait insolvable s'il coexiste avec
operator const float*() const {
return v;
}
Ça veut dire quoi, « insolvable », ici. Si j'écris unVec[x],
c'est l'opérateur [] qui sert ; s'il existe, on ne cherche pas
d'autres conversions.
float x() const { return v[0] ; }
je crois que l'on ne veut /pas/ de telles fonctions.
Pourquoi ?
Certes, mais le rôle des fonctions membres n'est-il pas
précisement de s'occuper de la représentation interne. Ou est-ce
que tu le trouves normal que la classe reserve l'interface
«@agréable » pour elle-même, et force les utilisateurs
d'utiliser celle moins agréable.
float{&} operator[] (char name) const {
if (name == 'x')
return v[0];
etc
}
Tu n'est pas sérieux, j'espère.
qui serait insolvable s'il coexiste avec
operator const float*() const {
return v;
}
Ça veut dire quoi, « insolvable », ici. Si j'écris unVec[x],
c'est l'opérateur [] qui sert ; s'il existe, on ne cherche pas
d'autres conversions.
float x() const { return v[0] ; }
je crois que l'on ne veut /pas/ de telles fonctions.
Pourquoi ?
Certes, mais le rôle des fonctions membres n'est-il pas
précisement de s'occuper de la représentation interne. Ou est-ce
que tu le trouves normal que la classe reserve l'interface
«@agréable » pour elle-même, et force les utilisateurs
d'utiliser celle moins agréable.
float{&} operator[] (char name) const {
if (name == 'x')
return v[0];
etc
}
Tu n'est pas sérieux, j'espère.
qui serait insolvable s'il coexiste avec
operator const float*() const {
return v;
}
Ça veut dire quoi, « insolvable », ici. Si j'écris unVec[x],
c'est l'opérateur [] qui sert ; s'il existe, on ne cherche pas
d'autres conversions.