Copie d'un objet, que se passe-t-il reelement? [SOLVED] [C++] - C++ - Programmation
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.
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.
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).
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!
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.
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 !
Marsh Posté le 23-07-2008 à 20:59:08
Cytoplasm a écrit : |
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... |
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) { 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.
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.
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.
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.
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
Je pense que tu devrais te renseigner sur les containers C++ : http://www.cplusplus.com/reference/stl/
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.
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
}
Marsh Posté le 24-07-2008 à 13:50:06
Ok, autant pour moi,je comprends ce que tu veux dire.
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.
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
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.
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.
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.
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 :
|
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.
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!
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.
Marsh Posté le 04-08-2008 à 11:21:50
J'aimerais bien voir la tête de ton truc final en fait par curiosité
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?
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