Vraag & Antwoord

Programmeren

[c++] delete this;

20 antwoorden
  • Als ik: [code:1:21a4241072] #include <iostream.h> class myClass { public: myClass() { } ~myClass() { } void deleteMe() { delete this; } }; main() { myClass *class0 = new myClass(); class0->deleteMe(); if(class0) cout << "Class0 bestaat nog steeds!!!!" << endl; } [/code:1:21a4241072] doe, dan is mijn class dus nog niet gedelete.... Hoe moet ik nou een class zichzelf laten deleten??? Bedankt, Barry Faas
  • [code:1:39d9442414] #include <iostream.h> class myClass { public: myClass() { } ~myClass() { } }; main() { myClass *class0 = new myClass(); delete class0; if(class0) cout << "Class0 bestaat nog steeds!!!!" << endl; } [/code:1:39d9442414]
  • [quote:0b6073df02="phaas"] ... Hoe moet ik nou een class [b:0b6073df02]zichzelf[/b:0b6073df02] laten deleten??? ... [/quote:0b6073df02]
  • 1. Waarom zou je dat willen? dit is SLECHT design :P (no hard feelings, maar jij zult voor je eigen "reference counter" moeten spelen en dit leid heel snel tot errors. 2. als je dit toch wilt doorzetten, kun je dit gebruiken: [code:1:2a6d27ecad] class RefClass { private: ~RefClass() { } // voorkom stack gebruik ->niets deleten int refs = 0; public: Create() { ++refs; } Delete() { --refs; if (refs == 0) delete this; } }; class VoorPhaas{ public: explicit VoorPhaas(RefClass obj) : obj_(obj) { obj_->Create; } ~VoorPhaas() { obj_->Delete(); } }; [/code:1:2a6d27ecad] Gebruik dus in ieder geval een controlling class hiervoor, anders zul je een goed assembly programmeur moeten zijn om hier zinvol mee om te gaan.
  • Wat ik nu precies wil doen is het volgende: Ik heb een callback-implentatie gemaakt, een beetje volgens het single-rooted concept (ongeveer net zoiets als Qt, maar dan geen MOC) Objecten kunnen dan runtime elkaar parent/child object zijn, bijv: [code:1:1999dc5e7a] class0 (super-class) | ---> class1 (child class) ---> class2 (child class) | | ----> class3 (child class) enz. [/code:1:1999dc5e7a] Als voor class0 de functie 'destroy()' wordt aangeroepen, stuurt deze een signal naar class1 en class2, vervolgens stuurt class2 een signal naar class3 welke zichzelf delete. Daarna deleten class1/2 zich zodat uiteindelijk class0 gedelete kan worden. Ik kan class2 nu bijv. wel 'zelf' class3 laten destroyen, oke... en class0, class1en2 laten deleten, maar wie delete nu uiteindelijk class0? Plus dat het volgens mij netter is om via een signal de classen zichzelf te laten opdoeken..... Advies required!!!!
  • [quote:33153e6cdb] Als voor class0 de functie 'destroy()' wordt aangeroepen, stuurt deze een signal naar class1 en class2, vervolgens stuurt class2 een signal naar class3 welke zichzelf delete. Daarna deleten class1/2 zich zodat uiteindelijk class0 gedelete kan worden. Ik kan class2 nu bijv. wel 'zelf' class3 laten destroyen, oke... en class0, class1en2 laten deleten, maar wie delete nu uiteindelijk class0? [/quote:33153e6cdb] De main-loop ;) [quote:33153e6cdb] Plus dat het volgens mij netter is om via een signal de classen zichzelf te laten [/quote:33153e6cdb] Als informaticus vind ik dat slecht design. Maar als je het per se wilt, creeer dan een controlling class die de reference counters bijhoud op de manier waarop ik het beschreven heb.
  • [quote:343c3deb23="w.roosenburg"] Als informaticus vind ik dat slecht design. Maar als je het per se wilt, creeer dan een controlling class die de reference counters bijhoud op de manier waarop ik het beschreven heb.[/quote:343c3deb23] Welke manier had je dan voor willen stellen?
  • Ikke nu niet meer begrijpen :lol: Dat code voorbeeld met die ref-class niet genoeg? :oops:
  • Nou, jij zegt dat je het een slecht design vindt.... wat vind je dan wel goed design? Zijn er andere oplossingen dan?
  • wel eens van het Singleton-pattern gehoord? Zo niet google maar ff. Het Singleton pattern beschrijft dat je een reeks van classes hebt, maar dat je elke class maar een keer instantieert. Je hebt dus nooit twee precies dezelfde objecten, natuurlijk wel verschillende afgeleide objecten van dezelfde superclass. Het object wat een ander object instantieert is ook de controlling class en die weet dus van het onderliggende object alles af en die heeft ook de verantwoordelijkheid van het deleten, dus daar kan het ook niet zo zijn dat de class zichzelf "delete", immers dan krijg je problemen met "wie bepaalt wanneer en waarom". De allereerste class instantieer je dus in je main loop.
  • Dat klinkt moeilijk :o Heb je niet wat meer voorbeelden? maw, ik google iig wel ff ;)
  • Oke, ik begin nu langzaam de moed te verliezen. Ik heb het volgende allemaal al je probeert: Een cleanuphandler maken, volgens dat singleton-princiepe die bijhoudt welke classes er geinstantieerd zijn en ze na het signal 'deleteLater' verwijderd. Een grote superclass die als ouder voor ALLE nieuwe object dient, deze verwijderd de object ook na het deleteLater signal. Ik heb zelfs de cleanuphandler al threads laten spawnen om objects te deleten. Maar niets werkt! alles compiled en runt goed zonder segfault (na hondert jaar prutsen) maar de objecten blijven however gewoon bestaan!! :o Maar dit werkt bv. ook niet: [code:1:1fc8a55676] class object { public: object() { } }; main() { object *myobject = new object(); delete object; if(object) cout << "En ja hoor, myobject bestaat nog steeds GRRRR"; } [/code:1:1fc8a55676] HEEEEEELLLLLPPP!!!
  • [code:1:bbcca38bea]class object { public: object() { } }; main() { object *myobject = new object(); delete myobject; if(object) cout << "En ja hoor, myobject bestaat nog steeds GRRRR"; } [/code:1:bbcca38bea] Let op wat je probeert te deleten. object kun je niet deleten omdat dat een type is en geen instantie. myobject is in dit geval de instantie van de klasse object en die kun je dus wel deleten.
  • Ja sorry, foute informatie ;) [code:1:c1d18b3665] delete myobject if(myobject) ... [/code:1:c1d18b3665] moet het natuurlijk gewoon zijn, maar dan werkt het alsnog niet.
  • [quote:b5b26dd892="phaas"]Wat ik nu precies wil doen is het volgende: Ik heb een callback-implentatie gemaakt, [/quote:b5b26dd892] Verklaar de term [i:b5b26dd892]callback-implementatie[/i:b5b26dd892]. (Tenminste, wat jij er onder verstaat.) Of is dit voor het probleem niet van belang? [quote:b5b26dd892="phaas"] een beetje volgens het single-rooted concept (ongeveer net zoiets als Qt, maar dan geen MOC) [/quote:b5b26dd892] "Qt", "MOC" ?? [quote:b5b26dd892="phaas"] Objecten kunnen dan runtime elkaar parent/child object zijn, bijv: [/quote:b5b26dd892] [i:b5b26dd892]Single-rooted[/i:b5b26dd892]. Dus ze kunnen elkaar niet circulair refereren? [quote:b5b26dd892="phaas"] [code:1:b5b26dd892] class0 (super-class) | ---> class1 (child class) ---> class2 (child class) | | ----> class3 (child class) enz. [/code:1:b5b26dd892] Als voor class0 de functie 'destroy()' wordt aangeroepen, stuurt deze een signal naar class1 en class2, vervolgens stuurt class2 een signal naar class3 welke zichzelf delete. Daarna deleten class1/2 zich zodat uiteindelijk class0 gedelete kan worden. Ik kan class2 nu bijv. wel 'zelf' class3 laten destroyen, oke... en class0, class1en2 laten deleten, maar wie delete nu uiteindelijk class0? [/quote:b5b26dd892] [quote="phaas"] class0 (super-class) is dus geen abstracte klasse? [quote:b5b26dd892="phaas"] Plus dat het volgens mij netter is om via een signal de classen zichzelf te laten opdoeken..... [/quote:b5b26dd892] Waarom wil je hier uberhaupt signals voor gebruiken? Als ik het goed begrijp dan hou je in elk object dus een lijstje bij met alle child objecten die onder dat desbetreffende object 'hangen'. Een soort [i:b5b26dd892]linked list[/i:b5b26dd892]. Om het even in de pseudo Pascal notatie te houden komt het dus op het volgende neer: [code:1:b5b26dd892] constructor TMyObject.Create begin List := Creer "List" end; destructor TMyObject.Destroy begin if (List.Count > 0) then begin for i := List.Count-1 to 0 do begin myObject(List.Items[i]).Free; myObject.Delete(i); end; end; List.Free; inherited Destroy; end; function TMyObject.AddChild(...) begin // voeg child toe aan de list... end;[/code:1:b5b26dd892] Gebruik: [code:1:b5b26dd892] mySuperObject := "creeer TMyObject" [...] mySuperObject.Free; mySuperObject := Nil; [/code:1:b5b26dd892] Wat je dan alleen maar hoeft te doen de super-class vrij te geven en het gehele object met alle childs wordt als een sneeuwbal effect opgedoekt!! Het principe van "Object georienteerd programmeren" Zoiets soortgelijks kun je dus implementeren...
  • [quote:ee8958f6cc="phaas"]Ja sorry, foute informatie ;) [code:1:ee8958f6cc] delete myobject if(myobject) ... [/code:1:ee8958f6cc] moet het natuurlijk gewoon zijn, maar dan werkt het alsnog niet.[/quote:ee8958f6cc] Mijn kennis over C++ rijkt niet zover en ik weet niet of dit automatisch door C++ wordt geregeld, maar... volgens mij heb je hier nog steeds e.o.a. pointer naar een stuk geheugen. Wat ik zou doen is nadat je het object vrijgegeven hebt deze verwijzing op NULL zetten. En bovendien, myobject een boolean???
  • [quote:a0295a5f64] Verklaar de term callback-implementatie. (Tenminste, wat jij er onder verstaat.) Of is dit voor het probleem niet van belang? [/quote:a0295a5f64] Een signal-slot systeem, net als Qt of libsigc++ gebruiken. met behulp van de CONNECT marco wordt een signal object gekoppeld aan een functie (slot), als het signal aangeroepen wordt, wordt indirect het slot aangeroepen. [quote:a0295a5f64] "Qt", "MOC" ?? [/quote:a0295a5f64] Qt -- crossplatform gui toolkit Moc -- Meta Object Compiler, een 'extensie' voor C++ om runtime informatie te kunnen krijgen over classen. Qt gebruikt dit voor hun signal-slot implentatie. [quote:a0295a5f64] Single-rooted. Dus ze kunnen elkaar niet circulair refereren? [/quote:a0295a5f64] Wow, wacht ff.. Alle object zijn afgeleidt van 1 class, pObject. Deze classes kunnen RUNTIME elkaar's parent/child object spelen, omdat het pObject-type linked lists bijhoudt van z'n children. Het idee hierachter is cleanup, een programmeur hoeft niet meer steeds zijn troep te deleten, want als er 1 object gedelete wordt, gaan alle children mee. Zo staat er dus nooit meer een waslijst aan pointers in de deconstructor. [quote:a0295a5f64] class0 (super-class) is dus geen abstracte klasse? [/quote:a0295a5f64] Daar heeft het volgens mij niets mee te maken, inheritting van het pObject-type is compile-time, maar het parent-child princiepe werkt slechts runtime. voorbeeld: (er vanuit gegaan dan mijnClass en mijnTweedeClass pObject zijn.) [code:1:a0295a5f64] mijnClass *mijnclass0 = new mijnClass(); // constuctor zonder parent object mijnTweedeClass *mijnclass1 = new mijnTweeClass(mijnclass0); // wordt child-object van mijnclass0 [/code:1:a0295a5f64] Als ik dus delete mijnclass0; doe, wordt mijnclass1 ook opgedoekt, en anders om, delete mijnclass1; verwijderd mijnclass0, no. 1 uit zijn linked-list. Dit gaat allemaal goed, behalve dan dat er niets verwijderd wordt. [quote:a0295a5f64] Mijn kennis over C++ rijkt niet zover en ik weet niet of dit automatisch door C++ wordt geregeld, maar... volgens mij heb je hier nog steeds e.o.a. pointer naar een stuk geheugen. Wat ik zou doen is nadat je het object vrijgegeven hebt deze verwijzing op NULL zetten. En bovendien, myobject een boolean??? [/quote:a0295a5f64] In mijn boek over C++ staat dat je elke met new() gecreeerde pointer met deallocaten met delete; myobject is geen boolean, maar het if() statement geeft true als een object niet-null is, false als het null is.
  • [quote:b8bde4914d="phaas"][quote:b8bde4914d] Verklaar de term callback-implementatie. (Tenminste, wat jij er onder verstaat.) Of is dit voor het probleem niet van belang? [/quote:b8bde4914d] Een signal-slot systeem, net als Qt of libsigc++ gebruiken. met behulp van de CONNECT marco wordt een signal object gekoppeld aan een functie (slot), als het signal aangeroepen wordt, wordt indirect het slot aangeroepen. [/quote:b8bde4914d] Volgens mij haal je je hiermee onnodig veel ellende op de hals zoals deadlock eigenschappen. [quote:b8bde4914d="phaas"] [quote:b8bde4914d] Single-rooted. Dus ze kunnen elkaar niet circulair refereren? [/quote:b8bde4914d] Wow, wacht ff.. Alle object zijn afgeleidt van 1 class, pObject. [/quote:b8bde4914d] Dus je hebt in principe maar één klasse object, die alle functionaliteit zou moeten bezitten om het geheel te kunnen laten werken? Omdat je het hebt over 'afleiden'... [quote:b8bde4914d="phaas"] Deze classes kunnen RUNTIME elkaar's parent/child object spelen, omdat het pObject-type linked lists bijhoudt van z'n children. Het idee hierachter is cleanup, een programmeur hoeft niet meer steeds zijn troep te deleten, want als er 1 object gedelete wordt, gaan alle children mee. [/quote:b8bde4914d] Alleen de parent kan children deleten. [quote:b8bde4914d="phaas"] Zo staat er dus nooit meer een waslijst aan pointers in de deconstructor. [/quote:b8bde4914d] Wat is in hemelsnaam een deconstructor? :roll: In de destructor staan nooit pointers! Het enige wat daar gebeurt is de cleanup code. [quote:b8bde4914d="phaas"] [quote:b8bde4914d] class0 (super-class) is dus geen abstracte klasse? [/quote:b8bde4914d] Daar heeft het volgens mij niets mee te maken, inheritting van het pObject-type is compile-time, maar het parent-child princiepe werkt slechts runtime. [/quote:b8bde4914d] Het gaat mij niet om hoe het technisch in elkaar zit, maar om te achterhalen wat jij nou precies wilt! [quote:b8bde4914d="phaas"] voorbeeld: (er vanuit gegaan dan mijnClass en mijnTweedeClass pObject zijn.) [code:1:b8bde4914d] mijnClass *mijnclass0 = new mijnClass(); // constuctor zonder parent object mijnTweedeClass *mijnclass1 = new mijnTweeClass(mijnclass0); // wordt child-object van mijnclass0 [/code:1:b8bde4914d] [/quote:b8bde4914d] Hier heb je het opeens over twee klassen, namelijk mijnClass en mijnTweedeClass i.p.v. pObject [quote:b8bde4914d="phaas"] Als ik dus delete mijnclass0; doe, wordt mijnclass1 ook opgedoekt, en anders om, delete mijnclass1; verwijderd mijnclass0, no. 1 uit zijn linked-list. [/quote:b8bde4914d] Dus mijnclass0 moet dan nog wel gewoon bestaan, maar heeft geen verwijzing meer naar mijnclass1? Zie mijn eerdere pseudo code, die alle child objecten verwijderd. In de destructor komt de meest cruciale code te staan. Daarnaast moet je denk ik met een soort GetParent() gaan werken, om vanuit de parent de child te deleten. [quote:b8bde4914d="phaas"] Dit gaat allemaal goed, behalve dan dat er niets verwijderd wordt. [/quote:b8bde4914d] Naast het destroyen van het object, moet je de inhoud van de list ook met één verlagen. [quote:b8bde4914d="phaas"] [quote:b8bde4914d] Mijn kennis over C++ rijkt niet zover en ik weet niet of dit automatisch door C++ wordt geregeld, maar... volgens mij heb je hier nog steeds e.o.a. pointer naar een stuk geheugen. Wat ik zou doen is nadat je het object vrijgegeven hebt deze verwijzing op NULL zetten. En bovendien, myobject een boolean??? [/quote:b8bde4914d] In mijn boek over C++ staat dat je elke met new() gecreeerde pointer met deallocaten met delete; myobject is geen boolean, maar het if() statement geeft true als een object niet-null is, false als het null is.[/quote:b8bde4914d] zoals ik al eerder zei... met delete geeft je alleen het gereserveerde geheugen weer vrij, waarbij je nog steeds een (ongeldige) pointer naar een stuk garbage geheugen hebt. (Het gebruik van deze pointer zal veelal resulteren in exception errors/access violation errors.) Na de delete dien je de variabele nog op NULL te zetten! Je hebt de volgende waarden: True, False en NULL! Vraag me alleen niet hoe die NULL technisch gerealiseerd is.
  • [quote:ec5211637b] Volgens mij haal je je hiermee onnodig veel ellende op de hals zoals deadlock eigenschappen. [/quote:ec5211637b] Wat zijn deadlock eigenschappen? [quote:ec5211637b] Dus je hebt in principe maar één klasse object, die alle functionaliteit zou moeten bezitten om het geheel te kunnen laten werken? Omdat je het hebt over 'afleiden'... [/quote:ec5211637b] Alle class in een programma inheritten een class genaamd pObject welke de functie bevat als connect (sig-slots), disconnect, functie's voor child-lists etc. [quote:ec5211637b] Alleen de parent kan children deleten. [/quote:ec5211637b] Als een child door een externe class wordt gedelete, moet de parent de pointer wissen en deze uit de lijst schrappen. [quote:ec5211637b] Wat is in hemelsnaam een deconstructor? In de destructor staan nooit pointers! Het enige wat daar gebeurt is de cleanup code. [/quote:ec5211637b] spelfout. In de destructor worden pointer gedeallocate, dus de helelijst met pointer aangemaakt in het vrij geheugen. [quote:ec5211637b] Het gaat mij niet om hoe het technisch in elkaar zit, maar om te achterhalen wat jij nou precies wilt! [/quote:ec5211637b] A. Pointer-deallocaten dmv het parent object + een object zichzelfs kunnen laten deleten evt. dmv van een cleanuphandler. [quote:ec5211637b] Hier heb je het opeens over twee klassen, namelijk mijnClass en mijnTweedeClass i.p.v. pObject [/quote:ec5211637b] class mijnClass : public pObject { ... }; class mijnTweedeClass : public pObject { ... }; mijnClass en mijnTweedeClass hoeven compile-time niets met elkaar te maken te hebben, alleen runtime wordt een instantie van mijnTweedeClass EEN child-object van mijnClass. [quote:ec5211637b] Dus mijnclass0 moet dan nog wel gewoon bestaan, maar heeft geen verwijzing meer naar mijnclass1? Zie mijn eerdere pseudo code, die alle child objecten verwijderd. In de destructor komt de meest cruciale code te staan. Daarnaast moet je denk ik met een soort GetParent() gaan werken, om vanuit de parent de child te deleten. [/quote:ec5211637b] Maar dat werkt nu juist niet!! dat is nu juist het probleem! dit staat LETTERLIJK in de broncode: [code:1:ec5211637b] uint i; for(i =0; i < _childList->count(); i++) if(_childList->at(i)) { pObject *child = _childList->at(i); _childList->remove(i); delete child; child = NULL; } [/code:1:ec5211637b]
  • [quote:a29ad67e8c="phaas"] [ ... ] [/quote:a29ad67e8c] Even overgeslagen... [quote:a29ad67e8c="phaas"] Maar dat werkt nu juist niet!! dat is nu juist het probleem! dit staat LETTERLIJK in de broncode: [code:1:a29ad67e8c] uint i; for (i =0; i < _childList->count(); i++) if(_childList->at(i)) { pObject *child = _childList->at(i); _childList->remove(i); delete child; child = NULL; } [/code:1:a29ad67e8c][/quote:a29ad67e8c] Dit komt niet overeen met eerdere code! 1. Je moet altijd het laaste item in de list wissen, of altijd item 0 wissen. 2. Daarnaast verwijder je eerst het item uit de lijst en daarna probeer je het object vrij te geven. :roll: [Edit: Zou op zich niets uit hoeven te maken. Slechts voor het geval er een fout op zou treden o.i.d.] unchecked code: [code:1:a29ad67e8c] uint i; for(i =_childList->count()-1; i >= 0; i--) if (_childList->at(i)) { pObject *child = _childList->at(i); delete child; _childList->remove(i); child = NULL; } [/code:1:a29ad67e8c] of [code:1:a29ad67e8c] uint i; for (i =0; i < _childList->count(); i++) if (_childList->at(0)) // controle is overbodig { pObject *child = _childList->at(0); delete child; _childList->remove(0); child = NULL; // volgens mij is deze nu overbodig. // In de parent zul je de verwijzing naar het gehele // object van deze klasse op NULL moeten zetten. } [/code:1:a29ad67e8c]

Beantwoord deze vraag

Weet jij het antwoord op deze vraag? Registreer of meld je aan met je account

Dit is een gearchiveerde pagina. Antwoorden is niet meer mogelijk.