Zeiger schützen
-
knivil schrieb:
const oder Referenzen.
const hilft gegen delete?
-
volkard schrieb:
knivil schrieb:
const oder Referenzen.
const hilft gegen delete?
k.A. kann aber grad nicht testen ... Waere aber bloed, wenn nicht. (so rein vom logischen, da ja beim Loeschen der Destruktor aufgerufen wird)
edit: Ich lese gerade ... operator delete private machen.
Symmetrieprinzip: Wenn deine Root-Klasse eine create-Methode anbietet, sollte sie auch eine destroy-Methode anbieten. Jaja ich reite wohl in letzter Zeit viel zu sehr drauf rum. Alternativ kannst du im Destruktor von Renderer es so einrichten, dass er sich automatisch aus der Liste entfernt (was aber eher unschoen ist).
-
knivil schrieb:
volkard schrieb:
knivil schrieb:
const oder Referenzen.
const hilft gegen delete?
k.A. kann aber grad nicht testen ... Waere aber bloed, wenn nicht. (so rein vom logischen, da ja beim Loeschen der Destruktor aufgerufen wird)
const hilft nicht gegen delete().
Stefan.
-
Warum eigentlich?
-
Why schrieb:
Warum eigentlich?
const Foo* foo = new Foo("Bar"); delete foo;
-
knivil schrieb:
edit: Ich lese gerade ... operator delete private machen.
Nette Idee. Oder gleich den ganzen Destruktor, vielleicht haben diese Objekte auch nichts auf dem Stack zu suchen.
-
maarp schrieb:
Nur eine Sache gefällt mir nicht: Durch die get() und create() Methoden kriegt der Anwender Zugriff auf den echten Zeiger. Wenn er auf den Rückgabewert delete aufruft, löscht er den Speicher, ohne das Foo das bemerkt.
Okay, aber macht man sowas?
delete root.getRenderer();Wenn man den Zeiger selbst oft abspeichert und weiterverwendet, kann das vielleicht eher passieren. Dann frage ich mich aber, ob der Benutzer sich wirklich so häufig mit rohen Zeigern rumschlagen muss. Und bei Factory-Methoden, die Zeiger zurückgeben, sollte Konvention sein, dass es ein Analogon zur Freigabe gibt. Insofern hat knivil schon Recht.
Klar ist es nicht grundsätzlich schlecht, böse Aktionen zu verhindern. Aber man muss sich auch überlegen, wo die Grenze ist, alles verhindern wird man nie können.
Gibst du deine Zeiger im Container auch wieder mal frei (also der Speicher dahinter)? Rohe Zeiger in Containern, die Objekte besitzen, finde ich etwas heikel. Vielleicht stellt Boosts PointerContainer-Bibliothek ein Alternative für dich dar (nur mal als Einwurf am Rande, ich will dir nicht zu gross im Design rumpfuschen)...
-
Nexus schrieb:
Gibst du deine Zeiger im Container auch wieder mal frei (also der Speicher dahinter)? Rohe Zeiger in Containern, die Objekte besitzen, finde ich etwas heikel. Vielleicht stellt Boosts PointerContainer-Bibliothek ein Alternative für dich dar (nur mal als Einwurf am Rande, ich will dir nicht zu gross im Design rumpfuschen)...
Ich habe eigentlich kein schlechtes Gewissen dabei, wenn das der DTor der besitzenden Klasse, in diesem Fall Root das macht.
-
Also ich will den Code unbedingt simpel halten und nicht "überdesigned".
Der Dtor von Root gibt den ganzen mit new angelegten Speicher wieder frei.Würde es nicht reichen, wenn die Klassen der zurückgelieferten Objekte (also Timer, Renderer etc), den Destructor und Constructor private machen und Root als friend deklarieren? Dann kann nur Root Objekte erzeugen/zerstören
-
@ volkard:
Naja, solange man nicht viel mit dem Container anstellt, kann auch nicht viel passieren. Ich sagte das vor allem, weil es hier bereits einige Leute gab, die entweder gar nicht wussten, dass man nicht nur Zeiger in Containern speichern kann, oder sich nicht im geringsten die Konsequenzen ausgemalt haben. Eindeletebei einemerase()geht schnell mal vergessen. Oder ein Container ist schnell kopiert, und der Zugriff kann eventuell sogar lange gut gehen.Ausserdem finde ich auch, man nutzt einen wichtigen Teil der Container nicht oder nur teilweise, wenn man wieder manuelle Speicherverwaltung hat. Ich habe das jedenfalls nicht so gern. Mein Einwand ist auch eher präventiv gemeint, eben weil recht viele Probleme entstehen können, an die man anfangs gar nicht denkt. Denn solange etwas gut geht und man sich keiner Problematik bewusst ist, wird man es weiter anwenden.
-
maarp schrieb:
Also ich will den Code unbedingt simpel halten und nicht "überdesigned".
Der Dtor von Root gibt den ganzen mit new angelegten Speicher wieder frei.Würde es nicht reichen, wenn die Klassen der zurückgelieferten Objekte (also Timer, Renderer etc), den Destructor und Constructor private machen und Root als friend deklarieren? Dann kann nur Root Objekte erzeugen/zerstören
Und Kopierkonstruktor und Zuweisungsoperator? Und Konstruktor und Zuweisungsoperator von Root auch private machen, sonst spielt man in der Tat mit Nexus' Gefahr.
-
Ähm, alles schön und gut. Aber wer sowas (in der Art) schon gesehen hat, versucht nicht mehr verkrampft, jede Verwendung von Rückgabewerten abzusichern...
int& get() { static int val = 10; return val; } int main() { delete &get(); }Ist natürlich Noob. Aber für einen etwas erfahreneren Programmierer ist auch klar, dass wenn in der Doku steht "returned Pointer is ownd by the producing class" dass ich den nicht löschen sollte...