[gelöst] [Anfänger] Delete von mit new erzeugten Objekten



  • Cosh schrieb:

    Alles wird mit new erzeugt.

    Erste Frage: Ist das wirklich immer nötig, oder reichen teilweise Objekte?

    Cosh schrieb:

    Jetzt müsste ich doch theoretisch auch alles wieder mit delete löschen, was ich zuvor mit new erzeugt habe oder?
    Irgendwie kommt mir das alles so viel und unübersichtlich vor.

    Ja, du musst delete dann auch aufrufen, ob direkt (durch dich) oder indirekt (in dem du mit entsprechenden Hilfskonstrukten arbeitest). Vielleicht solltest du mal ein Blick auf den TR1 oder Boost werfen. Im Speziellen geht es um Smartpointer (TR1, boost) sowie Zeigercontainer (boost).

    Einen einfachen Überblick z.B. über die Smartpointer von boost findest du hier (Kapitel 2).



  • Danke für eure Antworten. Ich denke das wird mir alles etwas weiter helfen. Vor allem die Sachte mit den Objekten auf dem Stack hab ich total vergessen.. Irgendwie kommt das bei mir wirklich aus der Java-Welt, dass ich alles mögliche mit "new" erzeuge. Aber in C++ gab es ja auch die andere Variante ohne new.
    Ja wie gesagt - fehlende Praxis 🙂
    Auch die Sache mit den Smartpointern wird mich sicherlich interessieren.

    Danke!



  • Verwende ein ungeschütztes new so wenig wie möglich. Besonders wenn dein Design komplexer wird, triffst du sonst auf eine Wand von Problemen (bezüglich Exceptionsicherheit, Besitzverhältnisse, einmalige Freigabe).

    Meist kannst du automatische Objekte verwenden, bei besitzenden Zeigern Smart-Pointer. Für mehrere gleiche Objekte gibt es Container (für Polymorphie z.B. extra angefertigte Pointer-Container in Boost).



  • Eine Frage hätte ich da noch...

    Ein vereinfachtes Beispiel was ich hier machen muss:

    Die KlasseB sieht in etwa so aus:

    class KlasseB
    {
    public:
    	std::string *betriebsnummer;
    	std::string *kommunikationsnummer;
    	std::string *kvpsnummer;
    // ...
    

    Da müssen doch also String-Referenzen hinein. Da muss ich doch mit new arbeiten!?

    So sieht meine Verwendung dieser Klasse in etwa an einem konkreten Beispiel aus:

    int meineFkt(struct* config conf) {
       KlasseA a;
    
       if(wasspezielles) {
          KlasseB b;
          b.betriebsnummer = new string(conf->betriebsnummer);
          b.kommunikationsnummer = new string(conf->kommunikationsnummer);
          b.kvpsnummer = new string(conf->kvpsnummer);
          a.blubb = &b;
       }
    
       // schlaue Sachen...
    
       delete a.blubb->betriebsnummer;
       delete a.blubb->kommunikationsnummer;
       delete a.blubb->kvpsnummer;
    }
    

    Ist das so in etwa gängig? Ich brauche all diese Objekte nach dem fkt-Aufruf nicht mehr. Aber da KlasseB einen Pointer auf einen String erwartet fällt mir nichts besseres als das "new" in diesem Fall ein. Ein &string(conf->betriebsnummer) wirft mir eine compilerwarnung aus: "taking address of temporary". Irgendwie klar - aber nichts anderes ist "a.blubb = &b" eigentlich auch und dort meckert er nicht.



  • Da müssen doch also String-Referenzen hinein. Da muss ich doch mit new arbeiten!?

    Nein, überhaupt nicht nötig, sondern nur fehleranfällig!

    Das soll eher so aussehen:

    class KlasseB
    {
    public:
        std::string betriebsnummer;
        std::string kommunikationsnummer;
        std::string kvpsnummer;
    // ...
    

    Ausserdem sollen die Member nicht public sein (auch in Java nicht...).

    Simon



  • Ja, aber die Klassen KlasseA und KlasseB wurden von gsoap erzeugt. Ich benutze sie nur. Ich kann sie nicht verändern. Das ist ja das Problem



  • Cosh schrieb:

    Da müssen doch also String-Referenzen hinein.

    Bitte spreche in C++ nicht von Referenzen, wenn es sich um Zeiger handelt. In Java wird zwar der Begriff Referenz benutzt, in C++ gibt es aber sowohl Zeiger als auch Referenzen. Java arbeitet eigentlich mit etwas das intern eher Zeiger sind, wenn auch mit einer "sicheren" Referenzsyntax (So "sicher" das ich durchaus häufiger in Javaprogrammen Null-Pointer-Exceptions gesehen habe).

    C++ Referenzen sind Aliasnamen für Variablen, sie SIND also (vereinfacht gesprochen) diese Variable. Für die reine Anwendung sind sie einfacher zu bedienen, müssen aber immer auf ein gültiges Objekt verweisen, und können nachträglich auch nicht "umgebogen" werden (Dirty Hacks lasse ich in einer sauberen Programmierung nicht gelten).

    Ja, aber die Klassen KlasseA und KlasseB wurden von gsoap erzeugt.
    

    Da wohl die wenigsten gsoap kennen, kann ich dazu nicht mehr sagen, als das dies scheinbar eine sehr dreckige C++ Umsetzung generiert. Und ja, wenn du dann etwas mit new allokierst, musst du dies auch mit delete aufräumen. Es sei den das berücksichtigt der erzeugte Code auch schon selber. Ohne eine komplette Klasse inklusive Implementierung kann ich das aber nicht sehen - hier solltest du dir die (hoffentlich vorhandene) Hilfe von gsoap anschauen.



  • @Artchi:

    C++ ist wohl eine der wenigen Sprachen, in denen man die meisten Möglichkeiten hat, Objekte zu verwalten.

    Der Einstiegssatz ist wohl etwas misslungen.

    Die meisten C++-Programmierer legen ihre Objekte auf dem Freestore (Freispeicher) an.

    Glaub ich nicht. Wird in keinem Tutorial so gezeigt, wieso sollte das jemand tun?

    Ansonsten ein netter Artikel.

    MfG SideWinder



  • Auch

    Die wenigsten C++-Programmierer wissen, das C++ komplexe Objekte wie native Datentypen behandelt

    ist eine etwas gewagte Aussage. 🙂

    Man bekommt ausserdem etwas den Eindruck, als ob bei

    std::string s("Hallo");
    

    keine dynamische Speicherverwaltung im Spiel wäre und nur der Stack genutzt würde.

    Aber das sind nur Details, die mir gerade aufgefallen sind. Sonst hast du dir echt Mühe gegeben, auch die Illustrationen tragen gut zum Verständnis bei.



  • Okay, danke für alle Antworten. Ich denke meine Frage wurde damit hinreichend beantwortet 🙂

    Schönes Wochenende!


Anmelden zum Antworten