for_each and delete.. ein Vergleich:
-
Hallo hab mich mal mit for_each von listen befasst.. und zwei Varianten implementiert.. nun die frage ob das auch elegant ist:)
class AllocNode{ . . . . Delete_Me(){ delete this; } } class Komb{ std::list<AllocNode*> LIST; deleteNodes(){ //ERSION A for(std::list<AllocNode*>::iterator S= LIST.begin(); S != LIST.end();S++) delete *S; //VERSION B std::for_each(m_lList.begin(), m_lList.end(),std::mem_fun(&AllocNode::Delete_Me)); //Liste löschen m_lList.clear(); } };Bei version A iteriere ich die Liste selber und gebe über den iterator jedes Objekt frei, VEriosn be benutzt ich die for_each funktion, und kann sogar eine memberfunktion benutzen ohne sie Delete_Me global zu machen? Nun frage ich ob diese methodik auch gut ist, da sich das objekt selber löscht, und ich nich wie bei Version A von ausen gelöscht wird... kritik?
Wenn ich nun Travesierungen mit forschleifen durch for_Each etc. ersetze, ereich somit eine höhere Performance?
-
glaub nicht, dass sich beide varianten von der performance her großartig unterscheiden werden. for_each wird intern auch nen iterator verwenden (ohne garantie ^^).
was ich aber nicht mag ist eine memberfunktion, die delete this verwendet. objekte, die sich selbst ins bein schiessen können sind mir suspekt ^^
-
ich mach die "delete this" variane auch nich gern.. aber so hab ich errreicht, das ich keine globale funktion verwenden muss..
Aber
AllocNode *A = new AllocNode(); A->delete_Me();und
AllocNode *A = new AllocNode(); delete A;sind ja aquvalent oder nich??
-
ja, aber was ist mit
AllocNode a; a.delete_Me();
-
hmm.. was würde da passieren?
Aber da Delete_Me() privat ist, und die Liste inter mit poitner verwaltet ist kann zwar ein Objekt statisch angelet werden, aber Delete_Me() nicht aufgerufen werden;)
-
Wenn Delete_Me privat ist, hat for_each ein Problem.
-
@David: im Prinzip schon, weil hier im Bsp. die funktion aus Komb aufgerufen wird.. in wirklickkeit rufe ich die funktion "deleteNode" aus CAllocNode aus (löschen der Kindknoten) wobei die Baumstruktur aller konten über die basis Liste verwaltet werden...
-
Deine "ERSION A" ist ganz klar zu bevorzugen - immerhin sind std::for_each und std::mem_fun auch freie Funktionen, welche ja bekanntlich ganz, ganz böse sind...
-
wenn sie so böse sind, wieso werden sie bereitgestellt... dachte "VERSION B" ist eleganter...
-
Die meisten C++-Programmierer sehen die Objektorientierung nicht so eng wie du
Und da C++ nunmal keine reine OO-Sprache ist, sind globale Funktionen durchaus üblich (und weite Teile der Standardbibliothek basieren nicht auf OO, sondern auf generischer Programmierung).(ich hab's dir schonmal gesagt - man kann's auch übertreiben mit der Objektorientierung ;))
-
BorisDieKlinge schrieb:
wenn sie so böse sind, wieso werden sie bereitgestellt... dachte "VERSION B" ist eleganter...
Vielleicht ist das bei dir nicht angekommen, aber finix' Beitrag war ironisch.
-
@MFK: hmm...sicher? Hört sich ehr zweideutig an
-
Wieso sollte eigentlich das Objekt wissen, wie es erstellt wurde? immerhin kann es ja im stack erstellt werden, mit new auf dem heap, es kann über ein placement new erstellt werden...das ist alles aufgabe der Datenstruktur die das Objekt erstellt hat, und darum sollte diese Datenstruktur auch das zerstören des objekts übernehmen.
-
ja gut, dann müsste der list container ja alle elemente mit delete löschen , bevor die zeiger gekickt werden oder nich?? Wäre noch besser;)
-
Version B finde ich deswegen Dreck weils 3x mehr Code ist + weniger übersichtlich = vollkommen unnötig.
Nur meine Meinung.Ideal wäre eine "shared_ptr" Liste oder ähnliches, dann tuts ein "list.clear();".
-
Ja, das wäre wohl besser - std::list<> macht das allerdings nicht. Eine Alternative wäre es, in Boost nach einer ptr_list zu suchen. Ansonsten würde ich die delete_element-Funktion entweder global oder als (statische?) Methode des list-Eigentümers anlegen.
-
@hustbear: und Version B ist evtl. noch laaanngsammer;)
-
BorisDieKlinge schrieb:
@hustbear: und Version B ist evtl. noch laaanngsammer;)
Nicht unbedingt
for_each() wird intern auch nur eine for-Schleife beinhalten, so daß der Compiler mit entsprechend guten Optimierungen (fast) identischen Code aus beiden Versionen erzeugen kann.
-
BorisDieKlinge schrieb:
@MFK: hmm...sicher? Hört sich ehr zweideutig an
Ich hatte versucht es zu verschleiern aber, tatsächlich, MFK ist mir auf die Schliche gekommen. Mein Beitrag war eher als Kommentar auf deine Furcht vor Verben zu verstehen.
-
hustbaer schrieb:
Version B finde ich deswegen Dreck weils 3x mehr Code ist + weniger übersichtlich = vollkommen unnötig.
Nur meine Meinung.Sehe ich irgendwie genau andersherum. Die Delete_Me-Methode ist natürlich nicht so schön, aber ersetzt man dies durch eine freie Funktion delete_foo finde ich die Zeile wesentlich übersichtlicher und klarer als die Schleife.