ou de ne garder que le tableau/vecteur et de faire des accesseurs x,y,z,
J'ai n'utilise que les accesseurs (qui sont inline) donc je peux changer l'implémentation à moindre frais. Mais, je ne sais pas alors comment conserver l'heritage.
Je ne pense pas que le jeux en vaille la chandelle.
j'en ai finalement l'impression aussi.
ou de ne garder que le tableau/vecteur et de faire
des accesseurs x,y,z,
J'ai n'utilise que les accesseurs (qui sont inline) donc je peux
changer l'implémentation à moindre frais. Mais, je ne sais pas alors
comment conserver l'heritage.
Je ne pense pas que le jeux en vaille la chandelle.
ou de ne garder que le tableau/vecteur et de faire des accesseurs x,y,z,
J'ai n'utilise que les accesseurs (qui sont inline) donc je peux changer l'implémentation à moindre frais. Mais, je ne sais pas alors comment conserver l'heritage.
Je ne pense pas que le jeux en vaille la chandelle.
j'en ai finalement l'impression aussi.
ALB
en fait, actuellement, j'ai ça :
class COORDONNEE_2D { private : int posX,posY; public : inline int GetposX(void) const { return posX;}; inline int SetposX(int px) { return posX=px;}; inline int GetposY(void) const { return posY;}; inline int SetposY(int py) { return posY=py;}; inline const COORDONNEE_2D& GetCOORDONNEE_2D(void) const { return *this;}; };
class COORDONNEE_3D : public COORDONNEE_2D { private : int posZ; public : COORDONNEE_3D(int posx=0,int posy=0,int posz=0):COORDONNEE_2D(posx,posy) { posZ=posz; }; COORDONNEE_3D(const COORDONNEE_2D &point2d,int posz=0):COORDONNEE_2D(point2d) { posZ=posz; }; COORDONNEE_3D(const COORDONNEE_3D &point3d):COORDONNEE_2D(point3d) { posZ=point3d.posZ; }; ~COORDONNEE_3D(void) {};
inline int GetposZ(void) const { return posZ;}; inline int SetposZ(int pz) { return posZ=pz;}; };
et je préferais ne pas renoncer à l'héritage.
en fait, actuellement, j'ai ça :
class COORDONNEE_2D
{
private :
int posX,posY;
public :
inline int GetposX(void) const { return posX;};
inline int SetposX(int px) { return posX=px;};
inline int GetposY(void) const { return posY;};
inline int SetposY(int py) { return posY=py;};
inline const COORDONNEE_2D& GetCOORDONNEE_2D(void) const { return
*this;};
};
class COORDONNEE_3D : public COORDONNEE_2D
{
private :
int posZ;
public :
COORDONNEE_3D(int posx=0,int posy=0,int
posz=0):COORDONNEE_2D(posx,posy) { posZ=posz; };
COORDONNEE_3D(const COORDONNEE_2D &point2d,int
posz=0):COORDONNEE_2D(point2d) { posZ=posz; };
COORDONNEE_3D(const COORDONNEE_3D &point3d):COORDONNEE_2D(point3d) {
posZ=point3d.posZ; };
~COORDONNEE_3D(void) {};
inline int GetposZ(void) const { return posZ;};
inline int SetposZ(int pz) { return posZ=pz;};
};
class COORDONNEE_2D { private : int posX,posY; public : inline int GetposX(void) const { return posX;}; inline int SetposX(int px) { return posX=px;}; inline int GetposY(void) const { return posY;}; inline int SetposY(int py) { return posY=py;}; inline const COORDONNEE_2D& GetCOORDONNEE_2D(void) const { return *this;}; };
class COORDONNEE_3D : public COORDONNEE_2D { private : int posZ; public : COORDONNEE_3D(int posx=0,int posy=0,int posz=0):COORDONNEE_2D(posx,posy) { posZ=posz; }; COORDONNEE_3D(const COORDONNEE_2D &point2d,int posz=0):COORDONNEE_2D(point2d) { posZ=posz; }; COORDONNEE_3D(const COORDONNEE_3D &point3d):COORDONNEE_2D(point3d) { posZ=point3d.posZ; }; ~COORDONNEE_3D(void) {};
inline int GetposZ(void) const { return posZ;}; inline int SetposZ(int pz) { return posZ=pz;}; };
et je préferais ne pas renoncer à l'héritage.
Sylvain Togni
Pourquoi ne pas utiliser dans la classe un int[3] ou, mieux, un vector<int> ?
je perds alors l'heritage. A moins qu'il y ait une astuce de vieux sioux ?
Je ne crois pas que faire hériter Point3D de Point2D soit une bonne conception. Un Point3D n'est pas un Point2D, il me semble. En quelles circonstances un tel héritage aide-t-il ?
-- Sylvain Togni
Pourquoi ne pas utiliser dans la classe un int[3] ou, mieux, un
vector<int> ?
je perds alors l'heritage.
A moins qu'il y ait une astuce de vieux sioux ?
Je ne crois pas que faire hériter Point3D de Point2D soit une
bonne conception. Un Point3D n'est pas un Point2D, il me semble.
En quelles circonstances un tel héritage aide-t-il ?
Pourquoi ne pas utiliser dans la classe un int[3] ou, mieux, un vector<int> ?
je perds alors l'heritage. A moins qu'il y ait une astuce de vieux sioux ?
Je ne crois pas que faire hériter Point3D de Point2D soit une bonne conception. Un Point3D n'est pas un Point2D, il me semble. En quelles circonstances un tel héritage aide-t-il ?
-- Sylvain Togni
ALB
Je ne crois pas que faire hériter Point3D de Point2D soit une bonne conception. Un Point3D n'est pas un Point2D, il me semble. En quelles circonstances un tel héritage aide-t-il ?
le relief est secondaire (essentiellement là pour faire beau à la sortie) et est "deduit" d'une analyse géométrique plane.
Je ne crois pas que faire hériter Point3D de Point2D soit une
bonne conception. Un Point3D n'est pas un Point2D, il me semble.
En quelles circonstances un tel héritage aide-t-il ?
le relief est secondaire (essentiellement là pour faire beau à la
sortie) et est "deduit" d'une analyse géométrique plane.
Je ne crois pas que faire hériter Point3D de Point2D soit une bonne conception. Un Point3D n'est pas un Point2D, il me semble. En quelles circonstances un tel héritage aide-t-il ?
le relief est secondaire (essentiellement là pour faire beau à la sortie) et est "deduit" d'une analyse géométrique plane.
ALB
Ce ne serait pas beau, mais on pourrait imaginer (non compilé) effectivement. Mais, je n'y avais pas penser.
Donc, est-ce que tout cela a un intérêt ? Pas sur...
Je dirais même "vraiment pas sûr ..."
ALB
Ce ne serait pas beau, mais on pourrait imaginer (non compilé)
effectivement. Mais, je n'y avais pas penser.
Donc, est-ce que tout cela a un intérêt ? Pas sur...
Ce ne serait pas beau, mais on pourrait imaginer (non compilé) effectivement. Mais, je n'y avais pas penser.
Donc, est-ce que tout cela a un intérêt ? Pas sur...
Je dirais même "vraiment pas sûr ..."
ALB
Sylvain
ALB wrote on 13/07/2006 17:18:
et je préferais ne pas renoncer à l'héritage.
pourquoi ? pour "faire de l'objet" ?
un modèle hiérarchique doit répondre à des besoins, c'est un moyen, pas une fin.
un tel modèle est généralement lié aux exigences sur les données, par exemple une classe de base définie des services mais ne réalise pas d'opérations car elle ne contient pas de données en propres, les classes filles ajoutent ou introduisent des données sur lesquelles reposent les opérations supplantées par ces classes.
votre besoin semble ici bien différent: vous aimeriez voir les coordonnées alignées/continues pour permettre une utilisation d'une instance point comme un GLint* à transmettre, notamment, aux fonctions glXXX2iv / glXXX3iv; ceci - ainsi que l'idée spontanée que l'on se fait d'un point (coordonnées dans un espace de 1 à N dimensions) - encourage à définir le plus tôt possible dans la hiérarchie ces données membres (les coordonnées).
donc un très simple, mais très efficace, int coords[3]; peut exister dès la classe de base - même si elle a vocation à ne représenter que 2 dimensions (la 3ième sera simplement non utilisée).
on peut ici hésiter(?) sur le représentation de ce tableau: un int [3] ou un vector<int>(3) ?
avec des int 32bits, le premier coute 12 octets, avec la STL 4.05:0009 de Plauger, le second coute 20 octets - faut-il dépenser 67% de plus et se priver de l'accès int* utile pour les glXXXNiv ? pour ma part, ce sera int[3].
vient alors le moyen d'accéder à ces données; dans votre post vous définissez posX, posY private pour Coord_2D, nécessairement vous définissez ensuite des accessors (get/set) pour chacune des variables.
une telle restriction d'accès ('private') est ici inutilement forte: a) toutes écritures *et* lectures sont possible via les accessors, b) l'origine de ces données est 'statique': des int possédés en propre par l'instance; et non une donnée dynamique résultant d'un stream parcouru, ni une valeur résultant d'un calcul, ni une valeur provenant d'un quelconque dispositif externe à l'instance.
pour illustrer ce dernier point, si les coordonnées étaient (par exemple) la position d'un mobile quelconque (poisson rouge ou satelitte), un membre privée 'localisateur' serait bienvenu; son type exact serait inconnu et les get() interrogeraient cet object à chaque lecture.
cette protection interroge également la relation entre classe parent et fille(s): avez-vous quelque raison de vous méfier de ce que fait Coord_3D pour l'empécher de manipuler les dimensions X et Y qui pourtant le caractérise pleinement (sont ces caractéristiques propres) ?
une définition 'protected' sera plus efficace à l'usage; les classes filles accèdent directement à leur description.
vient finalement le moyen d'accéder (lire/écrire/transmettre) ces données.
votre choix est très couteux, celui de Marc ("int& x() {return &(values[0]);}") est plus classique et bcp plus efficace.
si on le retient et ajoute un raccourci pour les fct glXXXNiv, il vient:
// get / set de chaque coordonnées int& x() { return coords[0]; } int& y() { return coords[1]; } // cast pour glXXXiv operator const GLint* () const { return coords; } };
et (pour faire beau(?))
class Coord_3D : public Coord_2D { public: Coord_3D() {} Coord_3D(int x, int y, int z):Coord_2D(x, y) { coords[2] = z; }
// get / set additionel int& z() { return coords[2]; } };
l'opérateur de cast permet d'écrire:
Coord_3D pt; glVertex3iv(pt);
assez sobre et efficace.
Sylvain.
-- OpenGL spécifique:
typedef int GLint;
les fcts OpenGL ont, par exemple, les prototypes: void glVertex3i (GLint x, GLint y, GLint z); void glVertex3iv(const GLint *v);
ALB wrote on 13/07/2006 17:18:
et je préferais ne pas renoncer à l'héritage.
pourquoi ? pour "faire de l'objet" ?
un modèle hiérarchique doit répondre à des besoins, c'est un moyen, pas
une fin.
un tel modèle est généralement lié aux exigences sur les données, par
exemple une classe de base définie des services mais ne réalise pas
d'opérations car elle ne contient pas de données en propres, les classes
filles ajoutent ou introduisent des données sur lesquelles reposent les
opérations supplantées par ces classes.
votre besoin semble ici bien différent: vous aimeriez voir les
coordonnées alignées/continues pour permettre une utilisation d'une
instance point comme un GLint* à transmettre, notamment, aux fonctions
glXXX2iv / glXXX3iv; ceci - ainsi que l'idée spontanée que l'on se fait
d'un point (coordonnées dans un espace de 1 à N dimensions) - encourage
à définir le plus tôt possible dans la hiérarchie ces données membres
(les coordonnées).
donc un très simple, mais très efficace, int coords[3]; peut exister dès
la classe de base - même si elle a vocation à ne représenter que 2
dimensions (la 3ième sera simplement non utilisée).
on peut ici hésiter(?) sur le représentation de ce tableau: un int [3]
ou un vector<int>(3) ?
avec des int 32bits, le premier coute 12 octets, avec la STL 4.05:0009
de Plauger, le second coute 20 octets - faut-il dépenser 67% de plus et
se priver de l'accès int* utile pour les glXXXNiv ? pour ma part, ce
sera int[3].
vient alors le moyen d'accéder à ces données; dans votre post vous
définissez posX, posY private pour Coord_2D, nécessairement vous
définissez ensuite des accessors (get/set) pour chacune des variables.
une telle restriction d'accès ('private') est ici inutilement forte:
a) toutes écritures *et* lectures sont possible via les accessors,
b) l'origine de ces données est 'statique': des int possédés en propre
par l'instance; et non une donnée dynamique résultant d'un stream
parcouru, ni une valeur résultant d'un calcul, ni une valeur provenant
d'un quelconque dispositif externe à l'instance.
pour illustrer ce dernier point, si les coordonnées étaient (par
exemple) la position d'un mobile quelconque (poisson rouge ou
satelitte), un membre privée 'localisateur' serait bienvenu; son type
exact serait inconnu et les get() interrogeraient cet object à chaque
lecture.
cette protection interroge également la relation entre classe parent et
fille(s): avez-vous quelque raison de vous méfier de ce que fait
Coord_3D pour l'empécher de manipuler les dimensions X et Y qui pourtant
le caractérise pleinement (sont ces caractéristiques propres) ?
une définition 'protected' sera plus efficace à l'usage; les classes
filles accèdent directement à leur description.
vient finalement le moyen d'accéder (lire/écrire/transmettre) ces données.
votre choix est très couteux, celui de Marc ("int& x() {return
&(values[0]);}") est plus classique et bcp plus efficace.
si on le retient et ajoute un raccourci pour les fct glXXXNiv, il vient:
un modèle hiérarchique doit répondre à des besoins, c'est un moyen, pas une fin.
un tel modèle est généralement lié aux exigences sur les données, par exemple une classe de base définie des services mais ne réalise pas d'opérations car elle ne contient pas de données en propres, les classes filles ajoutent ou introduisent des données sur lesquelles reposent les opérations supplantées par ces classes.
votre besoin semble ici bien différent: vous aimeriez voir les coordonnées alignées/continues pour permettre une utilisation d'une instance point comme un GLint* à transmettre, notamment, aux fonctions glXXX2iv / glXXX3iv; ceci - ainsi que l'idée spontanée que l'on se fait d'un point (coordonnées dans un espace de 1 à N dimensions) - encourage à définir le plus tôt possible dans la hiérarchie ces données membres (les coordonnées).
donc un très simple, mais très efficace, int coords[3]; peut exister dès la classe de base - même si elle a vocation à ne représenter que 2 dimensions (la 3ième sera simplement non utilisée).
on peut ici hésiter(?) sur le représentation de ce tableau: un int [3] ou un vector<int>(3) ?
avec des int 32bits, le premier coute 12 octets, avec la STL 4.05:0009 de Plauger, le second coute 20 octets - faut-il dépenser 67% de plus et se priver de l'accès int* utile pour les glXXXNiv ? pour ma part, ce sera int[3].
vient alors le moyen d'accéder à ces données; dans votre post vous définissez posX, posY private pour Coord_2D, nécessairement vous définissez ensuite des accessors (get/set) pour chacune des variables.
une telle restriction d'accès ('private') est ici inutilement forte: a) toutes écritures *et* lectures sont possible via les accessors, b) l'origine de ces données est 'statique': des int possédés en propre par l'instance; et non une donnée dynamique résultant d'un stream parcouru, ni une valeur résultant d'un calcul, ni une valeur provenant d'un quelconque dispositif externe à l'instance.
pour illustrer ce dernier point, si les coordonnées étaient (par exemple) la position d'un mobile quelconque (poisson rouge ou satelitte), un membre privée 'localisateur' serait bienvenu; son type exact serait inconnu et les get() interrogeraient cet object à chaque lecture.
cette protection interroge également la relation entre classe parent et fille(s): avez-vous quelque raison de vous méfier de ce que fait Coord_3D pour l'empécher de manipuler les dimensions X et Y qui pourtant le caractérise pleinement (sont ces caractéristiques propres) ?
une définition 'protected' sera plus efficace à l'usage; les classes filles accèdent directement à leur description.
vient finalement le moyen d'accéder (lire/écrire/transmettre) ces données.
votre choix est très couteux, celui de Marc ("int& x() {return &(values[0]);}") est plus classique et bcp plus efficace.
si on le retient et ajoute un raccourci pour les fct glXXXNiv, il vient:
peut-on être sûr que les entiers x et y se suivent en mémoire,quelque soit le compileur ? ( a-t-on *(&(A.x)+1) = A.y ?)
si, oui : class point3d : foo { int z; // des methodes };
point3d B;
peut-on être sûr que les entiers x, y et z se suivent en mémoire,quelque soit le compileur ? ( a-t-on *(&(B.x)+2) = B.z ?)
ALB
Et pourquoi (pour opengl) ne pas utiliser carrément un vecteur
float v|3]
Thierry
Cyrille
Je ne crois pas que faire hériter Point3D de Point2D soit une bonne conception. Un Point3D n'est pas un Point2D, il me semble. En quelles circonstances un tel héritage aide-t-il ?
le relief est secondaire (essentiellement là pour faire beau à la sortie) et est "deduit" d'une analyse géométrique plane.
Ca veut dire qu'il y aura un constructeur de Point3D qui acceptera un Point2D en paramètre, et mettra la composante z à zéro. Ca ne suggère pas du tout l'héritage.
-- C'est ma signature qu'elle est la mieux. Pas la vôtre.
Je ne crois pas que faire hériter Point3D de Point2D soit une
bonne conception. Un Point3D n'est pas un Point2D, il me semble.
En quelles circonstances un tel héritage aide-t-il ?
le relief est secondaire (essentiellement là pour faire beau à la
sortie) et est "deduit" d'une analyse géométrique plane.
Ca veut dire qu'il y aura un constructeur de Point3D qui acceptera un
Point2D en paramètre, et mettra la composante z à zéro. Ca ne suggère
pas du tout l'héritage.
--
C'est ma signature qu'elle est la mieux. Pas la vôtre.
Je ne crois pas que faire hériter Point3D de Point2D soit une bonne conception. Un Point3D n'est pas un Point2D, il me semble. En quelles circonstances un tel héritage aide-t-il ?
le relief est secondaire (essentiellement là pour faire beau à la sortie) et est "deduit" d'une analyse géométrique plane.
Ca veut dire qu'il y aura un constructeur de Point3D qui acceptera un Point2D en paramètre, et mettra la composante z à zéro. Ca ne suggère pas du tout l'héritage.
-- C'est ma signature qu'elle est la mieux. Pas la vôtre.