[SOLVED] [C++] Copie d'un objet, que se passe-t-il reelement?

Copie d'un objet, que se passe-t-il reelement? [SOLVED] [C++] - C++ - Programmation

Marsh Posté le 23-07-2008 à 18:29:20    

Salut a tous,
 
J'ai une petite question pour les gourous, merci d'avance!
 
Mettons que j'ai une classe Objet qui "new" des trucs dans son constructeur et les "delete" dans son destructeur.
Concretement, j'aimerait bien que quand un "new" soit appele, le "delete" correspondant soit appele plus tard pour eviter une fuite de memoire.
 
Maintenant si je copie un Objet A par un Objet B, est-ce que mes "free" de A vont etre appeles ou non?
 
code example:
 
Objet A, B;
A = B ;


Message édité par Cytoplasm le 24-07-2008 à 14:18:24
Reply

Marsh Posté le 23-07-2008 à 18:29:20   

Reply

Marsh Posté le 23-07-2008 à 20:01:40    

Ben si tu as un pointeur comme donnée membre de ta classe et que tu ne code pas ton opérateur d'affectation, ça va planter en sortant du scope de ta déclaration.
 
En effet tu va désallouer une première fois le pointeur que tu as alloué pour B lors de la destruction de A, puis une seconde lors de la destruction de B.
 
Bref il faut que tu fasses un opérateur d'affectation qui gère ça correctement; Fait aussi le constructeur de recopie tant qu'a faire, car le compilo ne va pas faire ce boulot a ta place, ni l'operateur = par défaut.


---------------
You can't start a fire with moonlight
Reply

Marsh Posté le 23-07-2008 à 20:10:16    

Ok, ok, le truc etait un peu plus complique que ca en verite, d'ou mon example un peu trop simplifie. En fait B est un pointeur, donc ca donne plutot ca: (caricaturalement, chacun de mes B1 ... Bn a une valeur et je veux retourner celui qui a la plus grande)
 
Objet A, *B1, *B2, ..., *Bn;
 
B1 = new Objet(...)
<...>
Bn = new Objet(...)
 
if (...) {
delete A
A = *B1
}else
delete B1
 
if (...) {
delete A
A = *B2
}else
delete B2
 
<...>
 
if (...) {
delete A
A = *Bn
}else
delete Bn
 
Bien sur, si je fais ca comme ca, ca marche pas vu que je peux pas faire le "delete A", mais dans l'esprit ca ressemble bien a ce que je veux faire.

Reply

Marsh Posté le 23-07-2008 à 20:32:10    

Ta méthode est chelou.
 
J'utiliserai plutôt un vecteur d'objets ou tu met tes B1 .. Bn, puis l'algo max_element pour récupèrer le plus grand élément de ton vecteur.  
 
Au pire si tu veux vraiment le faire mano a mano, met plutôt A sous la forme d'un pointeur que tu fait pointer sur le plus grand élément de ceux que tu a déjà testés, B1 ... Bn étant des objets (et non de pointeurs).


---------------
You can't start a fire with moonlight
Reply

Marsh Posté le 23-07-2008 à 20:36:06    

Oui mais... je peux pas vraiment mettre les B1 ... Bn dans un vecteur vu qu'il peut y en avoir infiniment beaucoup... c'est plus dans l'esprit
 
while(true) {
   Bx = generateMeANewB()
   if (...) {
     delete A
     A = *Bx
    }else
    delete Bx
}
 
Par contre, je vais peut etre changer le code pour utiliser des pointeurs en fait...
 
merci!

Reply

Marsh Posté le 23-07-2008 à 20:43:30    

Tiens d'ailleurs j'avais pas tilté mais faire un delete sur un objet qui n'est pas un pointeur c'est pas top, enfin ça compile pas sous visual en tout cas.


---------------
You can't start a fire with moonlight
Reply

Marsh Posté le 23-07-2008 à 20:46:34    

Ah ben oui, l'idee c'est que je veux faire est assez simple si on considere que A est un pointeur (d'ou le delete).
 
Par contre, si A est juste un objet, comment peut-on le faire, je ne sais toujours pas...
 
Bon de toute maniere je vais changer mon code pour faire un pointeur !

Reply

Marsh Posté le 23-07-2008 à 20:59:08    

Cytoplasm a écrit :


Objet A, *B1, *B2, ..., *Bn;
 
B1 = new Objet(...)
<...>
Bn = new Objet(...)


 
[:pingouino]
 

Cytoplasm a écrit :

Oui mais... je peux pas vraiment mettre les B1 ... Bn dans un vecteur vu qu'il peut y en avoir infiniment beaucoup...


 
http://img269.imageshack.us/img269/2212/pingouino7jm.png

Reply

Marsh Posté le 24-07-2008 à 07:53:49    

Cytoplasm a écrit :

Oui mais... je peux pas vraiment mettre les B1 ... Bn dans un vecteur vu qu'il peut y en avoir infiniment beaucoup... c'est plus dans l'esprit

 

while(true) {
   Bx = generateMeANewB()
   if (...) {
     delete A
     A = *Bx
    }else
    delete Bx
}

 

Par contre, je vais peut etre changer le code pour utiliser des pointeurs en fait...

 

merci!


Oui, on voit bien que c'est dans l'esprit "je vais faire plein de bugs et je serai incapable de débugger correctement".
Il existe pour chaque langage des manières standard de coder, des idiomes, et en C++, utiliser des collections pour ce genre d'opération en est une.
Fais ce que le monsieur t'a dit, gère les collections d'objet avec des collections, justement, ça sert à ça. Si tu as bcp d'objets, n'utilise pas un vecteur mais une liste, par ex, ou un deque et regarde s'il y a une fonction max qui permet de sélectionner l'objet max de ta collection, je suis sûr que ça existe.
Qq qui relit le code derrière voit tout de suite de quoi il en retourne, alors que dès qu'on lit ton code, on sent que le cerveau va chauffer inutilement arce que ça ne ressemble à rien.


Message édité par el muchacho le 24-07-2008 à 07:59:21

---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
Reply

Marsh Posté le 24-07-2008 à 08:31:46    

je pense que je donne pas la moyenne si un de mes étudiants me rends ça.
 
std::deque<T> suffira bien amplement, infiniment beaucoup, c'est pas ton probleme. Tu engrange dedans et basta.

Reply

Marsh Posté le 24-07-2008 à 08:31:46   

Reply

Marsh Posté le 24-07-2008 à 13:35:46    

Ok, ok c'est moche ce que je fais mais j'ai pas veritablement de choix.
C'est pas que j'aime pas vos solutions, ne vous meprenez pas: il y a veritablement une infinite d'objet B. Donc, comment je fais pour initialiser un vecteur avec? Genre je les evaluent tous et ca prend une infinite de temps? On voit bien que je suis oblige de faire ca un par un.
 
PS: a la question "mais si il y en a une infinite ca ne termine jamais?", la reponse est qu'il y a d'autres maniere de sortir de ce truc.
 

Reply

Marsh Posté le 24-07-2008 à 13:39:29    

Cytoplasm a écrit :

C'est pas que j'aime pas vos solutions, ne vous meprenez pas: il y a veritablement une infinite d'objet B.

 

Je vois mal comment tu peux avoir une infinité d'objets avec un nombre fini de variables. [:pingouino]

 
Cytoplasm a écrit :

Donc, comment je fais pour initialiser un vecteur avec? Genre je les evaluent tous et ca prend une infinite de temps?

 

Qu'appelles-tu "évaluer" ?

 
Cytoplasm a écrit :

On voit bien que je suis oblige de faire ca un par un.


Tout comme avec une list/deque/vector [:pingouino]

 

Je pense que tu devrais te renseigner sur les containers C++ :  http://www.cplusplus.com/reference/stl/


Message édité par Elmoricq le 24-07-2008 à 13:39:51
Reply

Marsh Posté le 24-07-2008 à 13:39:35    

Non, il n'y a pas une infinité d'objets. Il y en a un nombre fini mais non connu à l'avance et les collections n'ont aucun problème avec ça.
Ou alors tu as mal expliqué ton pb et de toute façon, le code que tu as soumis ne résoud pas le problème non plus.

 

Pour ce que tu fais, tu as besoin de :
deque:
http://www.cplusplus.com/reference/stl/deque/
max_element:
http://www.cplusplus.com/reference/algorithm/
deque::clear: et un constructeur de copie pour recopier l'objet avant de vider le container
http://www.cplusplus.com/reference [...] clear.html
ou alors de deque::erase.


Message édité par el muchacho le 24-07-2008 à 13:49:08

---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
Reply

Marsh Posté le 24-07-2008 à 13:48:49    

Quand meme, je sais a peu pres faire la difference entre une infinite et un nombre pas connu merci ;) Et le code fait ca tres bien: il ne genere les objets B qu'a la demande, les compare immediatement a A et les jetent s'ils servent a rien. A tout instant, j'ai le meilleur element.
 
while(l'utilisateur ne balance pas un Ctrl-C) {
   Bx = generateMeANewB()
   if (...) {
     delete A
     A = *Bx
    }else
    delete Bx
}  
 

Reply

Marsh Posté le 24-07-2008 à 13:50:06    

Ok, autant pour moi,je comprends ce que tu veux dire. :jap:
Il y en a un nombre fini à un instant T donné. En aucun cas tu peux mettre tous les objets en mémoire en même temps, donc le pb est le même avec ton truc.
Tu feras quand même mieux avec un deque, comme on te l'a dit, c'est plus propre.


Message édité par el muchacho le 24-07-2008 à 13:53:17

---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
Reply

Marsh Posté le 24-07-2008 à 13:53:38    

je me rend compte, que quand j'explique, je simplifie et apres les gens m'envoient des reponses trop simples, c'etait pas une bonne maniere d'expliquer mon probleme, desole :D
 
heu, j'arrive pas a voir comment faire ca avec un deque propre?
 
Notons que en plus, la question originiale n'est toujours pas resolue vue que je voulais que A soit un objet et non un pointeur.

Reply

Marsh Posté le 24-07-2008 à 13:58:37    

A un instant T donné, tu as par ex. une centaine d'objets *A en mémoire, que tu ajoutes avec la méthode push_back de deque.
Ensuite tu cherches le max avec max_element (ou en parcourant ton deque avec un itérateur), qui sera ta référence pour les comparaisons suivantes. Tu retires ton objet *A_max trouvé et enfin tu vides ton deque avec clear.
Et tu recommences jusqu'à ce que tous tes objets soient traités.
Maintenant, c'est vrai que si tu as des contraintes de temps réel et que tes objets *A sont créés au fil de l'eau, dans ce cas ta méthode est valable.
Quand au fait que tu veuilles A et non *A, ce ne serait pas inutile d'en motiver la raison.


Message édité par el muchacho le 24-07-2008 à 14:01:00

---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
Reply

Marsh Posté le 24-07-2008 à 14:08:29    

OK, tu veux faire ca par blocks dans le dequeue: C'est effectivement une solution possible. (Honnetement, je l'aime pas trop parce que ca complique un truc deja pas simple, mais ce serait envisageable)
 
En fait je voulais A et non *A pour des mauvaises raisons et j'ai donc change mon code pour utiliser *A. Donc maintenant, je serais juste curieux de voir si c'est possible de le faire avec A, meme si ce sera jamais implemente comme ca.

Reply

Marsh Posté le 24-07-2008 à 14:11:53    

Bah il reste toujours qu'en faisant un delete A, A n'étant pas un pointeur tu va pas aller loin.

 

Explique ton problème tel qu'il est ça aidera peut-être à apporter une solution.

 

Si l'idée c'est juste de générer des "B" tant que ton objet est pas plus grand que les précédent (optimisation d'un truc ?), dans ce cas tu n'as pas vraiment besoin de conteneur à mon sens, tu fait juste le test pour voir si le dernier est plus grand que le plus grand que tu as conservé.

 

Genre:

Code :
  1. Objet *bestSolution = NULL, candidate = NULL;
  2. While (/* condition d'arrêt parceque quand même c'est mieux*/)
  3. {
  4.    candidate = GenerateNewCandidate();
  5.    if (*candidate > *bestsolution)
  6.    {
  7.       if (NULL != bestSolution )
  8.       {
  9.          delete bestSolution ;
  10.          bestSolution = NULL;
  11.       }
  12.       bestSolution = candidate;
  13.    }
  14. }
 

Après on peut faire pas mal de choses, mais si c'est juste pour jouer a faire un truc pourri et mal pensé je voit pas l'intérêt.


Message édité par kyntriad le 24-07-2008 à 14:13:09

---------------
You can't start a fire with moonlight
Reply

Marsh Posté le 24-07-2008 à 14:17:35    

mmh, ca doit etre un peu bugge ca: *candidate > *bestsolution
 
et puis en fait, je voulais le contraire, genre Objet best, *candidate
 
Mais bon, je pense que ma question est effectivement sans grand interet vu que tout est un pointeur maintenant.
 
Merci a vous tous de m'avoir convaincu que ca devait etre le cas!

Reply

Marsh Posté le 24-07-2008 à 14:44:36    

Oui, et vraiment, il faut être plus précis quand on pose une question, parce qu'avec l'exemple que tu as donné, qui ne correspond pas vraiment à la téalité du pb, tu nous as mis sur une fausse piste.


---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
Reply

Marsh Posté le 04-08-2008 à 11:21:50    

J'aimerais bien voir la tête de ton truc final en fait par curiosité

Reply

Marsh Posté le 04-08-2008 à 14:23:10    

lu'! Alors la, je suis un peu surpris, pourquoi aller creuser les posts pour voir la solution du probleme d'un autre? ;)
 
Enfin bon, la solution, la voici: j'utilise des pointeurs. (Je te file pas de code a moins que tu le veuilles vraiment parce que le veritable code est un peu different par rapport a celui du post, mais, en tout cas, c'est tres proche de ce que j'ai deja post, au moins dans l'esprit)
 
Est-ce que ca satisfait ta curiosite?

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed