A défaut, quelle est la façon propre de faire un
// construire l'objet
MyClass *tmp = new MyClass();
// le placer dans le tableau
vec.push_back( *tmp );
// limérer la mémoire sans appeler le destructeur
free( tmp );
Je veux bien fournir mon propre copy constructor et lui faire créer un
nouvel objet de toutes pièces, mais cela est d'une part détourner son
vrai objectif et d'autre part cela risque d'interférer avec les vraies
copies d'objet.
"Cyrille "cns" Szymanski" a écrit dans le message de news:
Comment créer un tableau d'objets qui ne sont pas des copies d'un objet de départ.
Tu ne peux pas.
Chris
Christophe de Vienne
Cyrille "cns" Szymanski wrote:
En lisant tes différents posts, je me demande si ce n'est pas tout simplement un vecteur de pointeur (intelligent éventuellement) qu'il te faut : Les instances ne seront pas copiés, comme tu le souhaites.
Merci on me comprend !!! Exactement, sauf que je désire avoir un acces direct aux objets. Vu que tous mes objets ont la même taille, c'est un job idéal pour un tableau. Un MyClass[] est quand même beaucoup plus performant qu'un *MyClass[].
Mais ne pas copier tes instances n'est pas forcément moins performant que ce que tu suggères. Dans un fil de discussion récent le sujet est abordé.
Pour résumer, instancier un objet sur la pile puis le copier dans un emplacement déjà alloué (comme c'est le cas avec le reserve() de vector), peut s'avérer plus rapide qu'un new qui lui fait un appel système pour allouer de la mémoire. Ce que tu veux donc, c'est :
std::vector<MyClass> v;
for(int i = 0; i != 10; ++i) { v.push_back( MyClass() ); // l'objet temporaire est alloué sur la pile. }
En espérant que ça t'aide, et aussi ne pas avoir dit trop de bêtise...
A+
Christophe
-- Christophe de Vienne Experience is something you don't get until just after you need it. Oliver's Law.
Cyrille "cns" Szymanski wrote:
En lisant tes différents posts, je me demande si ce n'est pas tout
simplement un vecteur de pointeur (intelligent éventuellement) qu'il te
faut : Les instances ne seront pas copiés, comme tu le souhaites.
Merci on me comprend !!!
Exactement, sauf que je désire avoir un acces direct aux objets. Vu que
tous mes objets ont la même taille, c'est un job idéal pour un tableau. Un
MyClass[] est quand même beaucoup plus performant qu'un *MyClass[].
Mais ne pas copier tes instances n'est pas forcément moins performant que ce
que tu suggères. Dans un fil de discussion récent le sujet est abordé.
Pour résumer, instancier un objet sur la pile puis le copier dans un
emplacement déjà alloué (comme c'est le cas avec le reserve() de vector),
peut s'avérer plus rapide qu'un new qui lui fait un appel système pour
allouer de la mémoire.
Ce que tu veux donc, c'est :
std::vector<MyClass> v;
for(int i = 0; i != 10; ++i)
{
v.push_back( MyClass() ); // l'objet temporaire est alloué sur la pile.
}
En espérant que ça t'aide, et aussi ne pas avoir dit trop de bêtise...
A+
Christophe
--
Christophe de Vienne
Experience is something you don't get until just after you need it.
Oliver's Law.
En lisant tes différents posts, je me demande si ce n'est pas tout simplement un vecteur de pointeur (intelligent éventuellement) qu'il te faut : Les instances ne seront pas copiés, comme tu le souhaites.
Merci on me comprend !!! Exactement, sauf que je désire avoir un acces direct aux objets. Vu que tous mes objets ont la même taille, c'est un job idéal pour un tableau. Un MyClass[] est quand même beaucoup plus performant qu'un *MyClass[].
Mais ne pas copier tes instances n'est pas forcément moins performant que ce que tu suggères. Dans un fil de discussion récent le sujet est abordé.
Pour résumer, instancier un objet sur la pile puis le copier dans un emplacement déjà alloué (comme c'est le cas avec le reserve() de vector), peut s'avérer plus rapide qu'un new qui lui fait un appel système pour allouer de la mémoire. Ce que tu veux donc, c'est :
std::vector<MyClass> v;
for(int i = 0; i != 10; ++i) { v.push_back( MyClass() ); // l'objet temporaire est alloué sur la pile. }
En espérant que ça t'aide, et aussi ne pas avoir dit trop de bêtise...
A+
Christophe
-- Christophe de Vienne Experience is something you don't get until just after you need it. Oliver's Law.
Cyrille \cns\ Szymanski
Comment créer un tableau d'objets qui ne sont pas des copies d'un objet de départ.
Tu ne peux pas.
Je veux donc je peux :-)
C'est juste que la template vector ne me sera peut-être pas d'un grand seours.
Mais ne pas copier tes instances n'est pas forcément moins performant que ce que tu suggères. Dans un fil de discussion récent le sujet est abordé.
Références ?
Pour résumer, instancier un objet sur la pile puis le copier dans un emplacement déjà alloué (comme c'est le cas avec le reserve() de vector), peut s'avérer plus rapide qu'un new qui lui fait un appel système pour allouer de la mémoire.
Ce que tu veux donc, c'est :
Ce que je veux c'est dynamiquement allouer de la mémoire (un tableau de n objets, malloc( sizeof(MyClass)*n ) ) et instancier un objet à chaque emplacement (new (&vec[i]) MyClass()) ce qui est a mon avis un moyen assez performant pour instancier n objets et pouvoir y accéder rapidement ensuite.
Vous me direz que MyClass[] est là pour ça, mais en fait non car le tableau serait de taille fixe et je dois pouvoir ajouter et supprimer des objets à ma guise.
v.push_back( MyClass() ); // l'objet temporaire est alloué sur
Aïe, l'objet temporaire est détruit. Il faut donc que je ruse pour que le destructeur ne libère pas des ressources que la copie pourrait utiliser.
Merci beaucoup pour ces suggestions, -- _|_|_| CnS _|_| for(n=0;b;n++) _| b&=b-1; /*pp.47 K&R*/
Mais ne pas copier tes instances n'est pas forcément moins performant
que ce que tu suggères. Dans un fil de discussion récent le sujet est
abordé.
Références ?
Pour résumer, instancier un objet sur la pile puis le copier dans un
emplacement déjà alloué (comme c'est le cas avec le reserve() de
vector), peut s'avérer plus rapide qu'un new qui lui fait un appel
système pour allouer de la mémoire.
Ce que tu veux donc, c'est :
Ce que je veux c'est dynamiquement allouer de la mémoire (un tableau de n
objets, malloc( sizeof(MyClass)*n ) ) et instancier un objet à chaque
emplacement (new (&vec[i]) MyClass()) ce qui est a mon avis un moyen
assez performant pour instancier n objets et pouvoir y accéder rapidement
ensuite.
Vous me direz que MyClass[] est là pour ça, mais en fait non car le
tableau serait de taille fixe et je dois pouvoir ajouter et supprimer des
objets à ma guise.
v.push_back( MyClass() ); // l'objet temporaire est alloué sur
Aïe, l'objet temporaire est détruit. Il faut donc que je ruse pour que le
destructeur ne libère pas des ressources que la copie pourrait utiliser.
Merci beaucoup pour ces suggestions,
--
_|_|_| CnS
_|_| for(n=0;b;n++)
_| b&=b-1; /*pp.47 K&R*/
Mais ne pas copier tes instances n'est pas forcément moins performant que ce que tu suggères. Dans un fil de discussion récent le sujet est abordé.
Références ?
Pour résumer, instancier un objet sur la pile puis le copier dans un emplacement déjà alloué (comme c'est le cas avec le reserve() de vector), peut s'avérer plus rapide qu'un new qui lui fait un appel système pour allouer de la mémoire.
Ce que tu veux donc, c'est :
Ce que je veux c'est dynamiquement allouer de la mémoire (un tableau de n objets, malloc( sizeof(MyClass)*n ) ) et instancier un objet à chaque emplacement (new (&vec[i]) MyClass()) ce qui est a mon avis un moyen assez performant pour instancier n objets et pouvoir y accéder rapidement ensuite.
Vous me direz que MyClass[] est là pour ça, mais en fait non car le tableau serait de taille fixe et je dois pouvoir ajouter et supprimer des objets à ma guise.
v.push_back( MyClass() ); // l'objet temporaire est alloué sur
Aïe, l'objet temporaire est détruit. Il faut donc que je ruse pour que le destructeur ne libère pas des ressources que la copie pourrait utiliser.
Merci beaucoup pour ces suggestions, -- _|_|_| CnS _|_| for(n=0;b;n++) _| b&=b-1; /*pp.47 K&R*/
Cyrille \cns\ Szymanski
Comment créer un tableau d'objets qui ne sont pas des copies d'un objet de départ.
Tu ne peux pas.
Je veux donc je peux :-)
Mais ce que tu veux ne rempli pas forcément ton réel objectif (ie faire un code sûr et rapide)
Je veux juste un MyClass[] de taille variable.
En gros vous me proposez de créer un vector<MyClass> et d'ajouter les objets un par un : les instancier sur la pile puis les copier dans le tableau. Il faut aussi que dans le destructeur/constructeur je tienne compte du nombre de références pour ne pas libérer une ressource partagée par les différentes instances (c'est en fait illusoire car il n'y en a qu'une et elle est dans le tableau).
Je propose d'allouer de la place pour mes objets (créer un tableau) et de les instancier un par un en place.
Si quelqu'un me prouve que ma méthode est plus dangereuse et plus lente alors je l'appellerai Maître.
Comment créer un tableau d'objets qui ne sont pas des copies d'un
objet de départ.
Tu ne peux pas.
Je veux donc je peux :-)
Mais ce que tu veux ne rempli pas forcément ton réel objectif (ie
faire un code sûr et rapide)
Je veux juste un MyClass[] de taille variable.
En gros vous me proposez de créer un vector<MyClass> et d'ajouter les
objets un par un : les instancier sur la pile puis les copier dans le
tableau. Il faut aussi que dans le destructeur/constructeur je tienne
compte du nombre de références pour ne pas libérer une ressource partagée
par les différentes instances (c'est en fait illusoire car il n'y en a
qu'une et elle est dans le tableau).
Je propose d'allouer de la place pour mes objets (créer un tableau) et de
les instancier un par un en place.
Si quelqu'un me prouve que ma méthode est plus dangereuse et plus lente
alors je l'appellerai Maître.
Comment créer un tableau d'objets qui ne sont pas des copies d'un objet de départ.
Tu ne peux pas.
Je veux donc je peux :-)
Mais ce que tu veux ne rempli pas forcément ton réel objectif (ie faire un code sûr et rapide)
Je veux juste un MyClass[] de taille variable.
En gros vous me proposez de créer un vector<MyClass> et d'ajouter les objets un par un : les instancier sur la pile puis les copier dans le tableau. Il faut aussi que dans le destructeur/constructeur je tienne compte du nombre de références pour ne pas libérer une ressource partagée par les différentes instances (c'est en fait illusoire car il n'y en a qu'une et elle est dans le tableau).
Je propose d'allouer de la place pour mes objets (créer un tableau) et de les instancier un par un en place.
Si quelqu'un me prouve que ma méthode est plus dangereuse et plus lente alors je l'appellerai Maître.
Mais ne pas copier tes instances n'est pas forcément moins performant que ce que tu suggères. Dans un fil de discussion récent le sujet est abordé.
Références ?
<3f42503c$0$6221$
-- Christophe de Vienne Experience is something you don't get until just after you need it. Oliver's Law.
Christophe de Vienne
Cyrille "cns" Szymanski wrote:
Je propose d'allouer de la place pour mes objets (créer un tableau) et de les instancier un par un en place.
A partir du moment ou tu veux un tableau de taille dynamique tes objets seront forcéments copiés, si ce n'est à leur insertion, ne serait-ce qu'au redimensionnement de ton tableau.
A+
Christophe
-- Christophe de Vienne Experience is something you don't get until just after you need it. Oliver's Law.
Cyrille "cns" Szymanski wrote:
Je propose d'allouer de la place pour mes objets (créer un tableau) et de
les instancier un par un en place.
A partir du moment ou tu veux un tableau de taille dynamique tes objets
seront forcéments copiés, si ce n'est à leur insertion, ne serait-ce qu'au
redimensionnement de ton tableau.
A+
Christophe
--
Christophe de Vienne
Experience is something you don't get until just after you need it.
Oliver's Law.
Je propose d'allouer de la place pour mes objets (créer un tableau) et de les instancier un par un en place.
A partir du moment ou tu veux un tableau de taille dynamique tes objets seront forcéments copiés, si ce n'est à leur insertion, ne serait-ce qu'au redimensionnement de ton tableau.
A+
Christophe
-- Christophe de Vienne Experience is something you don't get until just after you need it. Oliver's Law.
Cyrille \cns\ Szymanski
il semble que tu prennes un malin plaisir à tout embrouiller dans le post d'après ;)
Peut-être que si tu reformulais ton problème tel qu'il est réellement, ie en montrant la classe des objets que tu veux gérer dans ton vector, ce serait un peu plus clair.
Voici donc plusieurs exemples concrets de classes dont je désire créer un tableau :
struct MyClass { int nb; MyClass() { nb = rand(); cout << "Objet " << nb << "n"; } ~MyClass() { cout << "Delete " << nb << "n"; } };
Il faut que les nombres contenus dans les éléments du tableau de MyClass soient différents (comme le ferait un "MyClass[] vec = new MyClass[]"), ce que ne fait pas un "vector<MyClass> vec(10)".
Un autre exemple : struct MyClass { HANDLE hwnd; MyClass() { hwnd = OpenHandle(); } ~MyClass() { CloseHandle( hwnd ); } };
Faire vector<MyClass> vec; for( i=0; i<10; ++i) { vec.push_back( MyClass() ); } ne fonctionne pas car le handle est fermé tout de suite.
Un exemple du même genre qui même s'il n'est pas très orthodoxe a l'avantage de compiler :
il semble que tu prennes un malin plaisir à tout embrouiller dans le
post d'après ;)
Peut-être que si tu reformulais ton problème tel qu'il est réellement,
ie en montrant la classe des objets que tu veux gérer dans ton vector,
ce serait un peu plus clair.
Voici donc plusieurs exemples concrets de classes dont je désire créer un
tableau :
struct MyClass {
int nb;
MyClass() {
nb = rand();
cout << "Objet " << nb << "n";
}
~MyClass() {
cout << "Delete " << nb << "n";
}
};
Il faut que les nombres contenus dans les éléments du tableau de MyClass
soient différents (comme le ferait un "MyClass[] vec = new MyClass[]"),
ce que ne fait pas un "vector<MyClass> vec(10)".
Un autre exemple :
struct MyClass {
HANDLE hwnd;
MyClass() {
hwnd = OpenHandle();
}
~MyClass() {
CloseHandle( hwnd );
}
};
Faire
vector<MyClass> vec;
for( i=0; i<10; ++i) {
vec.push_back( MyClass() );
}
ne fonctionne pas car le handle est fermé tout de suite.
Un exemple du même genre qui même s'il n'est pas très orthodoxe a
l'avantage de compiler :
il semble que tu prennes un malin plaisir à tout embrouiller dans le post d'après ;)
Peut-être que si tu reformulais ton problème tel qu'il est réellement, ie en montrant la classe des objets que tu veux gérer dans ton vector, ce serait un peu plus clair.
Voici donc plusieurs exemples concrets de classes dont je désire créer un tableau :
struct MyClass { int nb; MyClass() { nb = rand(); cout << "Objet " << nb << "n"; } ~MyClass() { cout << "Delete " << nb << "n"; } };
Il faut que les nombres contenus dans les éléments du tableau de MyClass soient différents (comme le ferait un "MyClass[] vec = new MyClass[]"), ce que ne fait pas un "vector<MyClass> vec(10)".
Un autre exemple : struct MyClass { HANDLE hwnd; MyClass() { hwnd = OpenHandle(); } ~MyClass() { CloseHandle( hwnd ); } };
Faire vector<MyClass> vec; for( i=0; i<10; ++i) { vec.push_back( MyClass() ); } ne fonctionne pas car le handle est fermé tout de suite.
Un exemple du même genre qui même s'il n'est pas très orthodoxe a l'avantage de compiler :
v.push_back( MyClass() ); // l'objet temporaire est alloué sur
Aïe, l'objet temporaire est détruit. Il faut donc que je ruse pour que le destructeur ne libère pas des ressources que la copie pourrait utiliser.
Mais dans ce cas, tu wrappes (emballe) ta "ressource" dans une classe rien que pour ça, qui devient membre de MyClass, et dont un rôle principal est de déterminer si, quand on passe par son destructeur, la ressource doit être libérée.
Ca sent le pointeur quelque part (dans la nouvelle classe, je dirais), et on me dit que ce que je raconte navigue entre les idées de pointeur intelligent, comptage de références et singleton. Seulement, je ne vois pas pourquoi tu t'acharnes sur cette histoire de temporaire : c'est pas parce qu'on passe dans un destructeur qu'on doit forcément jeter tout ce qu'il y avait dans l'instance...
En plus, jouer avec les vectors, malloc et des placement new... bien sûr je suis loin d'être un spécialiste, mais je pense que c'est louche. Tu dis que ton tableau doit être de taille "vraiment" dynamique, donc je suppose qu'à un moment tu vas faire quelque chose vec.reserve() ou vec.push_back() (si c'est un vector) ou un bon vieux realloc() qui sent le fromage... dans une opération de ce genre, il va bien falloir déplacer les éléments qui sont déjà dedans ? A part memcpy() et le passage par des constructeurs de copie, je ne vois pas beaucoup d'autre solution (1). La première, c'est pas "C++ fashion", et la deuxième laisse supposer que l'ancien tableau va (un jour) être libéré. Si ce n'est pas par free() (et j'imagine que faire free() sur un truc qui est passé par new laisse un état indéfini), ce sera par le destructeur des éléments de l'ancien tableau... et là, sans vouloir faire de mauvais esprit, comme tu disais :
Aïe, l'objet temporaire est détruit. Il faut donc que je ruse pour que le destructeur ne libère pas des ressources que la copie pourrait utiliser.
C'est très brouillon comme réflexion, mais je crois pas que tu puisses t'en tirer aussi indéfiniment que tu le souhaites avec les solutions que tu envisages.
Gourgouilloult du Clapotis En espérant ne pas en rajouter que du bruit... ;-/
(1) Sans trop y réfléchir, il est vrai.
Cyrille "cns" Szymanski wrote:
v.push_back( MyClass() ); // l'objet temporaire est alloué sur
Aïe, l'objet temporaire est détruit. Il faut donc que je ruse pour que le
destructeur ne libère pas des ressources que la copie pourrait utiliser.
Mais dans ce cas, tu wrappes (emballe) ta "ressource" dans une classe
rien que pour ça, qui devient membre de MyClass, et dont un rôle
principal est de déterminer si, quand on passe par son destructeur, la
ressource doit être libérée.
Ca sent le pointeur quelque part (dans la nouvelle classe, je dirais),
et on me dit que ce que je raconte navigue entre les idées de pointeur
intelligent, comptage de références et singleton. Seulement, je ne vois
pas pourquoi tu t'acharnes sur cette histoire de temporaire : c'est pas
parce qu'on passe dans un destructeur qu'on doit forcément jeter tout ce
qu'il y avait dans l'instance...
En plus, jouer avec les vectors, malloc et des placement new... bien sûr
je suis loin d'être un spécialiste, mais je pense que c'est louche.
Tu dis que ton tableau doit être de taille "vraiment" dynamique, donc je
suppose qu'à un moment tu vas faire quelque chose vec.reserve() ou
vec.push_back() (si c'est un vector) ou un bon vieux realloc() qui sent
le fromage... dans une opération de ce genre, il va bien falloir
déplacer les éléments qui sont déjà dedans ? A part memcpy() et le
passage par des constructeurs de copie, je ne vois pas beaucoup d'autre
solution (1). La première, c'est pas "C++ fashion", et la deuxième
laisse supposer que l'ancien tableau va (un jour) être libéré. Si ce
n'est pas par free() (et j'imagine que faire free() sur un truc qui est
passé par new laisse un état indéfini), ce sera par le destructeur des
éléments de l'ancien tableau... et là, sans vouloir faire de mauvais
esprit, comme tu disais :
Aïe, l'objet temporaire est détruit. Il faut donc que je ruse pour
que le destructeur ne libère pas des ressources que la copie
pourrait utiliser.
C'est très brouillon comme réflexion, mais je crois pas que tu puisses
t'en tirer aussi indéfiniment que tu le souhaites avec les solutions que
tu envisages.
Gourgouilloult du Clapotis
En espérant ne pas en rajouter que du bruit... ;-/
v.push_back( MyClass() ); // l'objet temporaire est alloué sur
Aïe, l'objet temporaire est détruit. Il faut donc que je ruse pour que le destructeur ne libère pas des ressources que la copie pourrait utiliser.
Mais dans ce cas, tu wrappes (emballe) ta "ressource" dans une classe rien que pour ça, qui devient membre de MyClass, et dont un rôle principal est de déterminer si, quand on passe par son destructeur, la ressource doit être libérée.
Ca sent le pointeur quelque part (dans la nouvelle classe, je dirais), et on me dit que ce que je raconte navigue entre les idées de pointeur intelligent, comptage de références et singleton. Seulement, je ne vois pas pourquoi tu t'acharnes sur cette histoire de temporaire : c'est pas parce qu'on passe dans un destructeur qu'on doit forcément jeter tout ce qu'il y avait dans l'instance...
En plus, jouer avec les vectors, malloc et des placement new... bien sûr je suis loin d'être un spécialiste, mais je pense que c'est louche. Tu dis que ton tableau doit être de taille "vraiment" dynamique, donc je suppose qu'à un moment tu vas faire quelque chose vec.reserve() ou vec.push_back() (si c'est un vector) ou un bon vieux realloc() qui sent le fromage... dans une opération de ce genre, il va bien falloir déplacer les éléments qui sont déjà dedans ? A part memcpy() et le passage par des constructeurs de copie, je ne vois pas beaucoup d'autre solution (1). La première, c'est pas "C++ fashion", et la deuxième laisse supposer que l'ancien tableau va (un jour) être libéré. Si ce n'est pas par free() (et j'imagine que faire free() sur un truc qui est passé par new laisse un état indéfini), ce sera par le destructeur des éléments de l'ancien tableau... et là, sans vouloir faire de mauvais esprit, comme tu disais :
Aïe, l'objet temporaire est détruit. Il faut donc que je ruse pour que le destructeur ne libère pas des ressources que la copie pourrait utiliser.
C'est très brouillon comme réflexion, mais je crois pas que tu puisses t'en tirer aussi indéfiniment que tu le souhaites avec les solutions que tu envisages.
Gourgouilloult du Clapotis En espérant ne pas en rajouter que du bruit... ;-/
(1) Sans trop y réfléchir, il est vrai.
Cyrille \cns\ Szymanski
A partir du moment ou tu veux un tableau de taille dynamique tes objets seront forcéments copiés, si ce n'est à leur insertion, ne serait-ce qu'au redimensionnement de ton tableau.
A partir du moment ou tu veux un tableau de taille dynamique tes
objets seront forcéments copiés, si ce n'est à leur insertion, ne
serait-ce qu'au redimensionnement de ton tableau.
A partir du moment ou tu veux un tableau de taille dynamique tes objets seront forcéments copiés, si ce n'est à leur insertion, ne serait-ce qu'au redimensionnement de ton tableau.