smart pointer und new



  • Wenn ich eine Klasse in nem Smartpointer verwalte, so muss ich mich nicht mehr um deren zerstörung kümmern, was ne prima Sache ist, aber was passiert, wenn die Klasse einen char * data; Typ hat?

    Den krieg ich ja nur mit new belegt, aber wie lösche ich den dann? Muss ich bevor der pointer mit dem letzten ownership aus dem scope geht, per hand ein delete machen?



  • Seikilos schrieb:

    Wenn ich eine Klasse in nem Smartpointer verwalte, so muss ich mich nicht mehr um deren zerstörung kümmern, was ne prima Sache ist, aber was passiert, wenn die Klasse einen char * data; Typ hat?

    Den krieg ich ja nur mit new belegt, aber wie lösche ich den dann? Muss ich bevor der pointer mit dem letzten ownership aus dem scope geht, per hand ein delete machen?

    Was spricht dagegen, das im Destruktor der Klasse zu tun ?
    Und wenn die Klasse vorgegeben ist, kannst Du einen Wrapper drumherum machen, der dann delete[]-ed.
    Übrigens: Du darfst nicht vergessen, Dich um "Kopien" zu kümmern (also operator=() und CopyCtor schreiben oder verbieten oder ... (im Endeffekt schreibst Du Dir einen smart_pointer nochmal selbst).

    Wenn Du insgesamt allerdings ein Umfeld vorgegebene findest, das Du nicht verändern kannst und in dem "ownership" weitestgehend "gefrickelt" ist, bleibt Dir nicht viel Anderes übrig, als mitzufrickeln.

    Gruß,

    Simon2.



  • Der struct selbst (erwischt, ist keine Klasse) hat nur einen impliziten destruktor, welcher leer ist, sprich dort wird nichts gelöscht, weil das Ding aus der C Welt stammt.
    Der simpelste, mir einfallende Weg ist in der Tat aus dem char * ein std::auto_ptr<char> zu machen, aber da würde ich die Definition ändern, welche automatisch generiert wird.

    Die andere Alternative fällt somit wohl auch flach, da von den structs nichts geerbt werden kann 😕

    Ein WrapperWrapper wäre wohl ne Lösung, der einen anderen Typen hat, aber selber nen dtor implementiert ... sehe ich das richtig?



  • Seikilos schrieb:

    Die andere Alternative fällt somit wohl auch flach, da von den structs nichts geerbt werden kann 😕

    Wieso sollte nicht von Structs geerbt werden können?



  • Verflucht, ich hab das mit einer anderen Sprache verwechselt.
    Dann kann ich das ja machen.

    Danke!



  • Seikilos schrieb:

    Verflucht, ich hab das mit einer anderen Sprache verwechselt

    mit welcher?



  • PHP

    *scherz*

    C#

    A struct cannot inherit from another struct or class, and it cannot be the base of a class. All structs inherit directly from System.ValueType, which inherits from System.Object.



  • Tachyon schrieb:

    Seikilos schrieb:

    Die andere Alternative fällt somit wohl auch flach, da von den structs nichts geerbt werden kann 😕

    Wieso sollte nicht von Structs geerbt werden können?

    Müsste der Dtor des struct nicht virtuell sein?



  • Bulli schrieb:

    Tachyon schrieb:

    Seikilos schrieb:

    Die andere Alternative fällt somit wohl auch flach, da von den structs nichts geerbt werden kann 😕

    Wieso sollte nicht von Structs geerbt werden können?

    Müsste der Dtor des struct nicht virtuell sein?

    Warum sollte er, wenn sonst nichts virtuell ist?



  • Der ist auch implizit, ich muss dann sicherstellen, dass niemand den neuen Typen in einen Base Container wirft, richtig? Dann würde mangels virtual der spezielle dtor nicht aufgerufen werden.

    Wie stelle ich da denn sicher, dass niemand die base instantiiert, wenn ich nicht an den header komme um den dtor pure virtual zu machen?



  • Vielleicht schildert Du mal, was Du überhaupt genau treibst.



  • Keine Ahnung um *welche* Smart-Pointer es jetzt geht, aber zumindest bei boost::shared_ptr braucht man keine virtuellen Destruktoren, da man einen "Deleter" angeben kann. Wird kein Deleter angegeben ist das Default ein Deleter der den Typ löscht mit dem man den shared_ptr initialisiert hat.
    Also bei

    shared_ptr<Base> p(new Derived());
    

    ist alles OK, egal ob Base nen virtuellen dtor hat.
    Bei

    Base* MakeDerived();
    shared_ptr<Base> p(MakeDerived());
    

    hätte man ein Problem wenn der Base-dtor nicht virtuell ist, da der shared_ptr ja mit einem Base* initialisiert wird. In dem Fall könnte man einen eigenen Deleter angeben, oder eben einfach den dtor virtuell machen.

    Auch Arrays lassen sich über shared_ptr verwalten, eben indem man einen dtor mitgibt der das Array mit "delete []" statt nur "delete" löscht.



  • Seikilos schrieb:

    Der struct selbst (erwischt, ist keine Klasse) ...

    Nix "erwischt":
    1.) Du hattes von einer Klasse geschrieben:

    Seikilos schrieb:

    ...was passiert, wenn die Klasse einen char * data; Typ hat?...

    2.) ein "struct" ist in C++ auch eine Klasse.
    3.) Ich hatte nichts von "erben gechrieben". Ein einfacher wrapper kann aggregiereren - und sollte das nach meiner Erfahrung auch tun. (Erben nur da, wo es wirklich notwendig ist bzw. seeehr große Vorteile hat).
    4.) Natürlich kannst Du in C++ auch von einem struct erben.

    Wenn Du natürlich gar nicht nach einer C++-Lösung (sondern einer C-Lösung) fragst, dann fällt natürlich RAII (und damit smart_pointer) sowieso flach und die Antwort lautet einfach: JA: Ohne RAII muss man sich um solche Sachen selbst kümmern. ... und Du musst malloc()/free() verwenden.

    .. und der Fall ist ein Beispiel für:

    Simon2. schrieb:

    ...
    Wenn Du insgesamt allerdings ein Umfeld vorgegeben findest, ... in dem "ownership" weitestgehend "gefrickelt" ist, bleibt Dir nicht viel Anderes übrig, als mitzufrickeln.

    :p 😃

    Gruß,

    Simon2.


Anmelden zum Antworten