Salut,
voici la petite question du soir, histoire d'être sûr de bien faire les
choses:
Quand vaut-il mieux utiliser des conteneurs de pointeurs? Quand le type
du conteneur est trop important pour une copie de ses membres? (Ex: une
classe?)
J'avoue que ce point n'est pas encore très clair pour moi...
Et en quoi différe l'utilisation d'une collection de pointeurs par
rapport à une collection de types?
Merci d'avance...
PS: je ne pense pas avoir correctement utilisé le maigre vocabulaire C++
que je connaisse, là aussi je dois progresser ;-)
Salut,
voici la petite question du soir, histoire d'être sûr de bien faire les
choses:
Quand vaut-il mieux utiliser des conteneurs de pointeurs? Quand le type
du conteneur est trop important pour une copie de ses membres? (Ex: une
classe?)
J'avoue que ce point n'est pas encore très clair pour moi...
Et en quoi différe l'utilisation d'une collection de pointeurs par
rapport à une collection de types?
Merci d'avance...
PS: je ne pense pas avoir correctement utilisé le maigre vocabulaire C++
que je connaisse, là aussi je dois progresser ;-)
Salut,
voici la petite question du soir, histoire d'être sûr de bien faire les
choses:
Quand vaut-il mieux utiliser des conteneurs de pointeurs? Quand le type
du conteneur est trop important pour une copie de ses membres? (Ex: une
classe?)
J'avoue que ce point n'est pas encore très clair pour moi...
Et en quoi différe l'utilisation d'une collection de pointeurs par
rapport à une collection de types?
Merci d'avance...
PS: je ne pense pas avoir correctement utilisé le maigre vocabulaire C++
que je connaisse, là aussi je dois progresser ;-)
Et en quoi différe l'utilisation d'une collection de pointeurs par
rapport à une collection de types?
Et en quoi différe l'utilisation d'une collection de pointeurs par
rapport à une collection de types?
Et en quoi différe l'utilisation d'une collection de pointeurs par
rapport à une collection de types?
le Saturday 13 December 2003 00:52, écrivit :Et en quoi différe l'utilisation d'une collection de pointeurs par
rapport à une collection de types?
tu veux dire une collection d'objets, j'imagine.
1/ un container va construire par copie chacun de ses éléments, ce qui
peut ne pas être possible, ou pas désirable (cas de classes
polymorphes par exple, ou aussi de très gros objets lents à copier -
genre 1Ko ou plus, je sais pas trop où on tracerait la frontière à
partir d'où il est considéré gênant de manipuler par copie)
2/ si tu choisis de mettre des pointeurs dans le container, la copie
et destruction de ces pointeurs ne fait rien sur l'objet référencé, et
ce sera à toi de gèrer la vie de tes objets alloués, de t'assurer
qu'ils seront désallouer une fois et une seule, etc.. avec des smart
pointers ça peut bien se passer (le container appelera le destructeur
des smart pointers, et ceux-ci finiront par désallouer l'objet sans
intervention manuelle), mais en gnéral c'est une source possible de
complications. aussi, l'accès aux objets référencés par les pointeurs
prendra un peu plus de temps, puisqu'il y a un niveau d'indirection
supplémentaire.. (ça se sentira lors de boucles sur l'étendue de la
collection avec une instruction très rapide, où le temps d'accès aura
donc une aprt importante)
C'est en fait les différences classiques entre sémantique objet
(copies duplique l'objet) et sémantique pointeur (copie d'une
référence, donc partage de l'objet référencé, mais avec ce que ça
implique de complication).
le Saturday 13 December 2003 00:52, zoubidaman@hotmail.com écrivit :
Et en quoi différe l'utilisation d'une collection de pointeurs par
rapport à une collection de types?
tu veux dire une collection d'objets, j'imagine.
1/ un container va construire par copie chacun de ses éléments, ce qui
peut ne pas être possible, ou pas désirable (cas de classes
polymorphes par exple, ou aussi de très gros objets lents à copier -
genre 1Ko ou plus, je sais pas trop où on tracerait la frontière à
partir d'où il est considéré gênant de manipuler par copie)
2/ si tu choisis de mettre des pointeurs dans le container, la copie
et destruction de ces pointeurs ne fait rien sur l'objet référencé, et
ce sera à toi de gèrer la vie de tes objets alloués, de t'assurer
qu'ils seront désallouer une fois et une seule, etc.. avec des smart
pointers ça peut bien se passer (le container appelera le destructeur
des smart pointers, et ceux-ci finiront par désallouer l'objet sans
intervention manuelle), mais en gnéral c'est une source possible de
complications. aussi, l'accès aux objets référencés par les pointeurs
prendra un peu plus de temps, puisqu'il y a un niveau d'indirection
supplémentaire.. (ça se sentira lors de boucles sur l'étendue de la
collection avec une instruction très rapide, où le temps d'accès aura
donc une aprt importante)
C'est en fait les différences classiques entre sémantique objet
(copies duplique l'objet) et sémantique pointeur (copie d'une
référence, donc partage de l'objet référencé, mais avec ce que ça
implique de complication).
le Saturday 13 December 2003 00:52, écrivit :Et en quoi différe l'utilisation d'une collection de pointeurs par
rapport à une collection de types?
tu veux dire une collection d'objets, j'imagine.
1/ un container va construire par copie chacun de ses éléments, ce qui
peut ne pas être possible, ou pas désirable (cas de classes
polymorphes par exple, ou aussi de très gros objets lents à copier -
genre 1Ko ou plus, je sais pas trop où on tracerait la frontière à
partir d'où il est considéré gênant de manipuler par copie)
2/ si tu choisis de mettre des pointeurs dans le container, la copie
et destruction de ces pointeurs ne fait rien sur l'objet référencé, et
ce sera à toi de gèrer la vie de tes objets alloués, de t'assurer
qu'ils seront désallouer une fois et une seule, etc.. avec des smart
pointers ça peut bien se passer (le container appelera le destructeur
des smart pointers, et ceux-ci finiront par désallouer l'objet sans
intervention manuelle), mais en gnéral c'est une source possible de
complications. aussi, l'accès aux objets référencés par les pointeurs
prendra un peu plus de temps, puisqu'il y a un niveau d'indirection
supplémentaire.. (ça se sentira lors de boucles sur l'étendue de la
collection avec une instruction très rapide, où le temps d'accès aura
donc une aprt importante)
C'est en fait les différences classiques entre sémantique objet
(copies duplique l'objet) et sémantique pointeur (copie d'une
référence, donc partage de l'objet référencé, mais avec ce que ça
implique de complication).
Samuel Krempp wrote in2/ si tu choisis de mettre des pointeurs dans le container, la copie
et destruction de ces pointeurs ne fait rien sur l'objet référencé, et
ce sera à toi de gèrer la vie de tes objets alloués, de t'assurer
qu'ils seront désallouer une fois et une seule, etc.. avec des smart
pointers ça peut bien se passer (le container appelera le destructeur
des smart pointers, et ceux-ci finiront par désallouer l'objet sans
intervention manuelle), mais en gnéral c'est une source possible de
complications. aussi, l'accès aux objets référencés par les pointeurs
prendra un peu plus de temps, puisqu'il y a un niveau d'indirection
supplémentaire.. (ça se sentira lors de boucles sur l'étendue de la
collection avec une instruction très rapide, où le temps d'accès aura
donc une aprt importante)
Là par contre ça coince...
Imaginons une classe A basique, avec constructeur, destructeur, variables
et fonctions membres:
class A
{
private:
A();
~A();
void foo();
int i;
}
Si je construit un vecteur de pointeurs de A:
std::vector<A*> vect;
comment je le remplis?
vect.push_back( new A );
comment j'utilise les fonctions de A depuis un iterateur?
for( int i = 0; i < vect.size(); ++i )
tu parlais de la gestion des suppressions... Ca se passe comment dans ce
cas là?
supprimer tous les éléments lors de la destruction...
Samuel Krempp <krempp@crans.truc.en.trop.ens-cachan.fr> wrote in
2/ si tu choisis de mettre des pointeurs dans le container, la copie
et destruction de ces pointeurs ne fait rien sur l'objet référencé, et
ce sera à toi de gèrer la vie de tes objets alloués, de t'assurer
qu'ils seront désallouer une fois et une seule, etc.. avec des smart
pointers ça peut bien se passer (le container appelera le destructeur
des smart pointers, et ceux-ci finiront par désallouer l'objet sans
intervention manuelle), mais en gnéral c'est une source possible de
complications. aussi, l'accès aux objets référencés par les pointeurs
prendra un peu plus de temps, puisqu'il y a un niveau d'indirection
supplémentaire.. (ça se sentira lors de boucles sur l'étendue de la
collection avec une instruction très rapide, où le temps d'accès aura
donc une aprt importante)
Là par contre ça coince...
Imaginons une classe A basique, avec constructeur, destructeur, variables
et fonctions membres:
class A
{
private:
A();
~A();
void foo();
int i;
}
Si je construit un vecteur de pointeurs de A:
std::vector<A*> vect;
comment je le remplis?
vect.push_back( new A );
comment j'utilise les fonctions de A depuis un iterateur?
for( int i = 0; i < vect.size(); ++i )
tu parlais de la gestion des suppressions... Ca se passe comment dans ce
cas là?
supprimer tous les éléments lors de la destruction...
Samuel Krempp wrote in2/ si tu choisis de mettre des pointeurs dans le container, la copie
et destruction de ces pointeurs ne fait rien sur l'objet référencé, et
ce sera à toi de gèrer la vie de tes objets alloués, de t'assurer
qu'ils seront désallouer une fois et une seule, etc.. avec des smart
pointers ça peut bien se passer (le container appelera le destructeur
des smart pointers, et ceux-ci finiront par désallouer l'objet sans
intervention manuelle), mais en gnéral c'est une source possible de
complications. aussi, l'accès aux objets référencés par les pointeurs
prendra un peu plus de temps, puisqu'il y a un niveau d'indirection
supplémentaire.. (ça se sentira lors de boucles sur l'étendue de la
collection avec une instruction très rapide, où le temps d'accès aura
donc une aprt importante)
Là par contre ça coince...
Imaginons une classe A basique, avec constructeur, destructeur, variables
et fonctions membres:
class A
{
private:
A();
~A();
void foo();
int i;
}
Si je construit un vecteur de pointeurs de A:
std::vector<A*> vect;
comment je le remplis?
vect.push_back( new A );
comment j'utilise les fonctions de A depuis un iterateur?
for( int i = 0; i < vect.size(); ++i )
tu parlais de la gestion des suppressions... Ca se passe comment dans ce
cas là?
supprimer tous les éléments lors de la destruction...
class A
{
private:
public:A();
~A();
void foo();
protected:int i;
}
Si je construit un vecteur de pointeurs de A:
std::vector<A*> vect;comment je le remplis?
vect.push_back( new A );comment j'utilise les fonctions de A depuis un iterateur?
for( int i = 0; i < vect.size(); ++i )
vect[i]->foo();tu parlais de la gestion des suppressions... Ca se passe comment dans
ce cas là?
supprimer tous les éléments lors de la destruction...
for( int i = 0; i < vect.size(); ++i )
delete vect[i];
Ca se manipule comme des pointeurs quoi...
--------------------------------------------
Benoît Rousseau : roussebe at spray dot se
Jouez en programmant : http://realtimebattle.sourceforge.net/
class A
{
private:
public:
A();
~A();
void foo();
protected:
int i;
}
Si je construit un vecteur de pointeurs de A:
std::vector<A*> vect;
comment je le remplis?
vect.push_back( new A );
comment j'utilise les fonctions de A depuis un iterateur?
for( int i = 0; i < vect.size(); ++i )
vect[i]->foo();
tu parlais de la gestion des suppressions... Ca se passe comment dans
ce cas là?
supprimer tous les éléments lors de la destruction...
for( int i = 0; i < vect.size(); ++i )
delete vect[i];
Ca se manipule comme des pointeurs quoi...
--------------------------------------------
Benoît Rousseau : roussebe at spray dot se
Jouez en programmant : http://realtimebattle.sourceforge.net/
class A
{
private:
public:A();
~A();
void foo();
protected:int i;
}
Si je construit un vecteur de pointeurs de A:
std::vector<A*> vect;comment je le remplis?
vect.push_back( new A );comment j'utilise les fonctions de A depuis un iterateur?
for( int i = 0; i < vect.size(); ++i )
vect[i]->foo();tu parlais de la gestion des suppressions... Ca se passe comment dans
ce cas là?
supprimer tous les éléments lors de la destruction...
for( int i = 0; i < vect.size(); ++i )
delete vect[i];
Ca se manipule comme des pointeurs quoi...
--------------------------------------------
Benoît Rousseau : roussebe at spray dot se
Jouez en programmant : http://realtimebattle.sourceforge.net/
OK, merci beaucoup...
Si j'ai bien compris, cela me permettra d'utiliser moins de mémoire, mais
sera plus long dans les accès aux classes, c'est bien ça?
Non, tu n'utilises pas moins de mémoire avec les pointeurs... tu en
Sinon, avec les smart_pointers (c'est bien dans Boost ça?), ça se passe
comment??
Il y a plein de cas différents... boost propose 5 types de smart ptr
OK, merci beaucoup...
Si j'ai bien compris, cela me permettra d'utiliser moins de mémoire, mais
sera plus long dans les accès aux classes, c'est bien ça?
Non, tu n'utilises pas moins de mémoire avec les pointeurs... tu en
Sinon, avec les smart_pointers (c'est bien dans Boost ça?), ça se passe
comment??
Il y a plein de cas différents... boost propose 5 types de smart ptr
OK, merci beaucoup...
Si j'ai bien compris, cela me permettra d'utiliser moins de mémoire, mais
sera plus long dans les accès aux classes, c'est bien ça?
Non, tu n'utilises pas moins de mémoire avec les pointeurs... tu en
Sinon, avec les smart_pointers (c'est bien dans Boost ça?), ça se passe
comment??
Il y a plein de cas différents... boost propose 5 types de smart ptr
1/ un container va construire par copie chacun de ses éléments, ce qui peut
ne pas être possible, ou pas désirable (cas de classes polymorphes par
exple, ou aussi de très gros objets lents à copier - genre 1Ko ou plus, je
sais pas trop où on tracerait la frontière à partir d'où il est considéré
gênant de manipuler par copie)
1/ un container va construire par copie chacun de ses éléments, ce qui peut
ne pas être possible, ou pas désirable (cas de classes polymorphes par
exple, ou aussi de très gros objets lents à copier - genre 1Ko ou plus, je
sais pas trop où on tracerait la frontière à partir d'où il est considéré
gênant de manipuler par copie)
1/ un container va construire par copie chacun de ses éléments, ce qui peut
ne pas être possible, ou pas désirable (cas de classes polymorphes par
exple, ou aussi de très gros objets lents à copier - genre 1Ko ou plus, je
sais pas trop où on tracerait la frontière à partir d'où il est considéré
gênant de manipuler par copie)
Au moment où le profiler commence à râler.
Si un objet a une sémantique de valeur (et a priori pas de fonctions
virtuelles), j'utilise d'abord la solution la plus simple, i.e.
insertion dans le conteneur par copie, quelle que soit la taille de
l'objet (que je ne connais pas forcément, d'ailleurs). Si à
l'exécution, ça prend trop de temps ou trop de RAM, je change.
Au moment où le profiler commence à râler.
Si un objet a une sémantique de valeur (et a priori pas de fonctions
virtuelles), j'utilise d'abord la solution la plus simple, i.e.
insertion dans le conteneur par copie, quelle que soit la taille de
l'objet (que je ne connais pas forcément, d'ailleurs). Si à
l'exécution, ça prend trop de temps ou trop de RAM, je change.
Au moment où le profiler commence à râler.
Si un objet a une sémantique de valeur (et a priori pas de fonctions
virtuelles), j'utilise d'abord la solution la plus simple, i.e.
insertion dans le conteneur par copie, quelle que soit la taille de
l'objet (que je ne connais pas forcément, d'ailleurs). Si à
l'exécution, ça prend trop de temps ou trop de RAM, je change.
oui, enfin, il n'est qd même pas interdit de décider au départ qu'on va
manipuler telle classe par sémantique pointeur. genre des images.
oui, enfin, il n'est qd même pas interdit de décider au départ qu'on va
manipuler telle classe par sémantique pointeur. genre des images.
oui, enfin, il n'est qd même pas interdit de décider au départ qu'on va
manipuler telle classe par sémantique pointeur. genre des images.
le Wednesday 17 December 2003 13:53, écrivit :Au moment où le profiler commence à râler.
mais ça prend du temps de lui permettre de râler - ou de voir qu'il
râle. (si le cteur de copie a été inliné par exple, ce n'est pas
immédiat)
Si un objet a une sémantique de valeur (et a priori pas de fonctions
virtuelles), j'utilise d'abord la solution la plus simple, i.e.
insertion dans le conteneur par copie, quelle que soit la taille de
l'objet (que je ne connais pas forcément, d'ailleurs). Si à
l'exécution, ça prend trop de temps ou trop de RAM, je change.
oui, enfin, il n'est qd même pas interdit de décider au départ qu'on
va manipuler telle classe par sémantique pointeur. genre des images.
Il est fort possible que le prog puisse être lancé sur des images
32x32 qui seraient copiées sans aucun impact, mais le cas contraire
est aussi possible, et il est raisonnable de tout de suite opter pour
une sémantique de pointeur, pour éviter d'introduire une dépendance de
la complexité du prog sur la taille de l'image inutilement à certains
endroits du code. (ça dépend de ce que fait le prog, c'est sûr..)
On peut aussi, de manière générale, miser sur le fait qu'une
'optimisation' possible n'aurait de toute façon au pire pas d'impact
négatif sur les perfs, et perdrait moins de temps à coder directement
que d'obtenir confirmation par le profiler.
Je ne sais pas si c'est dû à un mauvais profiler, mais chez moi le
choix inlinée/pas inlinée pour chaque fonction un peu cruciale (et
autres choix lourds de conséquences) mène à un grand nombre (2^N) de
profiles éventuellement très différents à analyser.. à moins
d'intuition (mais c'est l'écueil qu'on veut éviter avec le profiling)
enfin bref parfois ça peut prendre du temps de profiler. (d'autant
qu'il faut éventuellement trouver des conditions d'éxécutions
réfléchissant bien le contexte final d'utilisation ! - ce qui est
d'ailleurs forcément un peu impossible qd on écrit une bibli)
le Wednesday 17 December 2003 13:53, gramster@gramster.com écrivit :
Au moment où le profiler commence à râler.
mais ça prend du temps de lui permettre de râler - ou de voir qu'il
râle. (si le cteur de copie a été inliné par exple, ce n'est pas
immédiat)
Si un objet a une sémantique de valeur (et a priori pas de fonctions
virtuelles), j'utilise d'abord la solution la plus simple, i.e.
insertion dans le conteneur par copie, quelle que soit la taille de
l'objet (que je ne connais pas forcément, d'ailleurs). Si à
l'exécution, ça prend trop de temps ou trop de RAM, je change.
oui, enfin, il n'est qd même pas interdit de décider au départ qu'on
va manipuler telle classe par sémantique pointeur. genre des images.
Il est fort possible que le prog puisse être lancé sur des images
32x32 qui seraient copiées sans aucun impact, mais le cas contraire
est aussi possible, et il est raisonnable de tout de suite opter pour
une sémantique de pointeur, pour éviter d'introduire une dépendance de
la complexité du prog sur la taille de l'image inutilement à certains
endroits du code. (ça dépend de ce que fait le prog, c'est sûr..)
On peut aussi, de manière générale, miser sur le fait qu'une
'optimisation' possible n'aurait de toute façon au pire pas d'impact
négatif sur les perfs, et perdrait moins de temps à coder directement
que d'obtenir confirmation par le profiler.
Je ne sais pas si c'est dû à un mauvais profiler, mais chez moi le
choix inlinée/pas inlinée pour chaque fonction un peu cruciale (et
autres choix lourds de conséquences) mène à un grand nombre (2^N) de
profiles éventuellement très différents à analyser.. à moins
d'intuition (mais c'est l'écueil qu'on veut éviter avec le profiling)
enfin bref parfois ça peut prendre du temps de profiler. (d'autant
qu'il faut éventuellement trouver des conditions d'éxécutions
réfléchissant bien le contexte final d'utilisation ! - ce qui est
d'ailleurs forcément un peu impossible qd on écrit une bibli)
le Wednesday 17 December 2003 13:53, écrivit :Au moment où le profiler commence à râler.
mais ça prend du temps de lui permettre de râler - ou de voir qu'il
râle. (si le cteur de copie a été inliné par exple, ce n'est pas
immédiat)
Si un objet a une sémantique de valeur (et a priori pas de fonctions
virtuelles), j'utilise d'abord la solution la plus simple, i.e.
insertion dans le conteneur par copie, quelle que soit la taille de
l'objet (que je ne connais pas forcément, d'ailleurs). Si à
l'exécution, ça prend trop de temps ou trop de RAM, je change.
oui, enfin, il n'est qd même pas interdit de décider au départ qu'on
va manipuler telle classe par sémantique pointeur. genre des images.
Il est fort possible que le prog puisse être lancé sur des images
32x32 qui seraient copiées sans aucun impact, mais le cas contraire
est aussi possible, et il est raisonnable de tout de suite opter pour
une sémantique de pointeur, pour éviter d'introduire une dépendance de
la complexité du prog sur la taille de l'image inutilement à certains
endroits du code. (ça dépend de ce que fait le prog, c'est sûr..)
On peut aussi, de manière générale, miser sur le fait qu'une
'optimisation' possible n'aurait de toute façon au pire pas d'impact
négatif sur les perfs, et perdrait moins de temps à coder directement
que d'obtenir confirmation par le profiler.
Je ne sais pas si c'est dû à un mauvais profiler, mais chez moi le
choix inlinée/pas inlinée pour chaque fonction un peu cruciale (et
autres choix lourds de conséquences) mène à un grand nombre (2^N) de
profiles éventuellement très différents à analyser.. à moins
d'intuition (mais c'est l'écueil qu'on veut éviter avec le profiling)
enfin bref parfois ça peut prendre du temps de profiler. (d'autant
qu'il faut éventuellement trouver des conditions d'éxécutions
réfléchissant bien le contexte final d'utilisation ! - ce qui est
d'ailleurs forcément un peu impossible qd on écrit une bibli)