Vererbung und destruktor



  • Hallo,
    Ich habe eine kurze Frage zu einem Programmstück aus einer Musterlösung:

    Business:Business(Giro* giro, int kreditkartennummer) : Giro(giro->getkontoNr(), giro->getInhaber(), giro->getBlz(), giro->getSaldo(), giro->getDispozins()), this->kreditkartennummer(kreditkartennummer){
    
        this->kreditkartennummer = kreditkartennummer;
    
        delete giro;
    
    }
    

    Business ist eine Klasse, welche von Giro erbt.
    Wenn ich also Giro zerstöre, bleiben dann die Werte der Variablen weiterhin für Business zugänglich? Zumal ich den char* inhaber zusätzlich im destructor von Giro freigebe?

    Wäre sowas nicht noch notwendig, oder aufgrund der private Variablen in Giro gar nicht möglich:

    this->kontoNr = giro->kontoNr;
        this->inhaber = giro->inhaber;
        this->blz     = giro->blz;
        this->saldo   = giro->saldo;
        this->dispoZins = giro->dispozins;
    

    Danke für die Hilfe,
    Das verwirrt mich etwas



  • Oha, das sieht sehr merkwürduig aus.
    Zeig bitte mal den Kontext, in dem ein Business Objekt erzeugt wird. Ich fürchte Schlimmes.


  • Mod

    Die Antwort ist: Kommt auf Giro an. Was du aber nicht zeigst.

    Die wahre Antwort ist aber: Mach das auf gar keinen Fall! Ein jedes Objekt ist selber für seine Ressourcen verantwortlich. Das ist ein ganz fundamentales Prinzip, wie man in C++ Programme schreiben sollte (Und auch in anderen Sprachen, aber C++ ist wirklich um dieses Prinzip herum designed). Dann funktioniert alles ganz wunderbar und toll von alleine (siehe Rule of zero). Wenn man versucht, selber rumzupfuschen, dann kommt auch nur Pfusch raus.

    Überhaupt ist da noch mehr falsch: this->kreditkartennummer wird uninitialisiert benutzt. Wieso gibt es das überhaupt doppelt? Hat Giro keinen Kopierkonstruktor? Wieso überhaupt Zeiger?


  • Mod

    SeppJ schrieb:

    this->kreditkartennummer wird uninitialisiert benutzt.

    Wo? Ich sehe nur ein this->kreditkartennummer in der Mem-Initialisierungsliste, was aber keine mem-initializer-id darstellt.


  • Mod

    camper schrieb:

    SeppJ schrieb:

    this->kreditkartennummer wird uninitialisiert benutzt.

    Wo? Ich sehe nur ein this->kreditkartennummer in der Mem-Initialisierungsliste, was aber keine mem-initializer-id darstellt.

    Mein Browserfenster ist nicht lang genug, du hast Recht. Da ist noch eine Klammer.



  • Ich wollte meinen Beitrag jetzt nicht überladen, und es geht aj auch nur darum, das Prinzip der Vererbung darzustellen, keine Sorge.

    Aber okay,

    Business:

    Business : public Giro
    - int kreditkartenNr

    + Business(int kontoNr, char *inhaber, int kreditkartenNr, int blz = 56250033,
    double saldo = 0, float dispoZins = 10.5)
    + Business(Giro *giro, int kreditkartenNr)

    Business erbt wiederum von einer Klasse mit namen Giro, welche wiederum von einer Oberklasse namens Konto erbt. (So in der Aufgabe)

    Kann mir jetzt eine Antwort auf meine Frage gegeben werden, oder braucht ihr noch was?



  • Ohne auf das Design einzugehen:

    Ja, die Variablen bleiben zugänglich. Im Konstruktor werden Kopien der Variablen von giro erzeugt und dem neuen Business Objekt zugewiesen. Du kannst also bedenkenlos darauf zugreifen.

    Wenn das die Musterlösung ist dann solltest du den ganzen Mist nur so lange behalten, wie du ihn brauchst. Danach am Besten alles vergessen, was dir dieser Dozent beigebracht hat.

    Edit:
    Da war ich etwas voreilig. Wenn mind. ein Giro member ein Pointer ist, der dem Objekt giro gehört, kann es einen Speicherzugriffsfehler geben. Zeig uns bitte die Definition von Giro und Business .



  • Also erstens: Wenn das wirklich so in der Musterlösung steht, schmeiß die Musterlösung weg!

    Wenn ich also Giro zerstöre, bleiben dann die Werte der Variablen weiterhin für Business zugänglich? Zumal ich den char* inhaber zusätzlich im destructor von Giro freigebe?

    Du hast da ja mehrere Giros. Nämlich einmal das übergebene und einmal ist dein Business auch ein Giro. Du kopierst die Daten bereits bei der Initialisierung. Daher sind nach dem delete die Werte in this-> noch gültig, während die giro-> nicht mehr nutzen darfst. Den Inhaber darfst du allerdings überhaupt nicht mehr verwenden, denn du hast nun nur den Pointer auf einen gelöschten Inhaber.

    Also: warum char*? Wenn, dann wenigstens const char*? Aber warum nicht einfach std::string nehmen? Dann musst du dir darum keine Gedanken machen.

    Ansonsten, wie hier schon angemerkt wurde, ist das absoluter Schrott und nie und nimmer eine Musterlösung, eher eine Antimusterlösung.



  • Ah, dankeschön. Genau das war meine Frage. 🙂

    Ob der code besonders schön ist, sei mal dahingestellt. 😃

    Schönen Tag euch!

    Ich habe in der Aufgabe (Aus einer Klausur) nur ein Klassendiagramm gegeben.
    In der Teilaufgabe ging es nur darum, den Konstruktor anzugeben.



  • Nur mal aus Böswilligkeit:
    Zeig dem Dozenten mal diesen Code und frag ihn, warum dir das um die Ohren fliegt.

    #include "giro.h"
    #include "business.h"
    
    int main()
    {
       Giro* g1 = new Giro( /* Parameter einsetzen */ );
       Business b1( g1, 100 );
       Business b2( g1, 200 );
       Business b3( &b2, 300 );
    }
    

    @Neugear:
    Dann nimm eine BigInteger Bibliothek und rechne in 0.0001 Cent-Einheiten. Oder noch kleiner, bis es passt.

    Edit:
    Wenn du __int64 benutzt und in 0.001 Cent-Einheiten rechnest kannst du immer noch mit bis zu +/- 9.223.372.036.854€ rechnen.



  • Igl schrieb:

    Ah, dankeschön. Genau das war meine Frage. 🙂

    Ob der code besonders schön ist, sei mal dahingestellt. 😃

    Schönen Tag euch!

    Ich habe in der Aufgabe (Aus einer Klausur) nur ein Klassendiagramm gegeben.
    In der Teilaufgabe ging es nur darum, den Konstruktor anzugeben.

    Dann gibt es für das Delete im Konstruktor bestimmt Punktabzug! Du solltest dir direkt angewöhnen "schönen" Code zu schreiben. Schlechte Angewohnheiten kriegt man nur schwer abgewöhnt!



  • @OT: Ist das jetzt die Musterlösung oder ist nur die Signatur vorgegeben und die Implementation ist von dir?



  • Business : public Giro

    bedeutet "ein Business IST ein Giro"

    sind deine Namen nur schlecht gewählt?

    dann eher BusinessKonto: public GiroKonto...?

    https://florian.adamsky.it/teaching/swt/08-komposition-aggregation.pdf



  • Ähm, habe das mal kurz überflogen. Nach diesen Slides solltest du NICHT lernen.

    Am ärgsten ist Slide 11 (Seite 13), wo new in einer Loop mit delete[] kombiniert wird.

    Aber auch schon vorher bei dem Auto stellt sich die Frage, warum es nicht, wie im UML dargestellt, einen Motor hat, sondern einen Benzinmotor. Wie schön auch, dass eine 1..*-Beziehung durch ein 4-elementiges C-Array dargestellt wird.

    Und Vererbung bei Schachfiguren? Ist das nicht schon Overengineering?



  • Ja ist nicht perfekt aber auch nicht super schlecht


Anmelden zum Antworten