Problem mit Vector und polymorphie



  • wichtig ist beim destruktor erstmal das virtual in vererbungsdingen



  • Das public sagt aus, dass die Vererbung öffentlich ist. Es gibt auch private Vererbungen (was der Default ist, wenn man den Modifier weglässt), dann erbt die Klasse zwar, aber niemand weiß es (unter anderem werden dann auch die public-Member der Oberklasse zu private-Membern der Unterklasse). Es gibt sogar protected-Vererbung, die man noch weniger braucht. C++ geht hier eben den Weg, so viel wie möglich Flexibilität anzubieten, auch auf Kosten der Komplexität der Sprache.

    Davon abgesehen gibt es noch ein paar andere Stellen in deinem Code, die du besser machen solltest bzw. wo sich C++ anders als PHP verhält:

    1. Generell sind Objekte auf dem Stack zu bevorzugen, da brauchst du dich um die Freigabe nicht zu kümmern und sie sind auch noch schneller. Das heißt insbesondere, solange es nicht einen sehr guten Grund gibt, den Vector dynamisch anzulegen (gibt es meinstens nicht), sollte man da keinen Zeiger nehmen, sondern einfach

    std::vector<Actions::Action*> actionStack;
    

    Beachte: kein Zeiger, kein new.

    2. Das gleiche Argument könnte man auch auf die Elemente des Vectors anwenden. Normalerweise gibt es keinen Grund, Zeiger in einen Vector zu stecken. Es sei denn man braucht wie in diesem Fall Polymorphie. Trotzdem haben Zeiger das Problem, dass man sie manuell aufräumen muss. Deshalb bieten sich Smart-Pointer an, die das für dich erledigen. Wenn du C++11 nimmst, ist unique_ptr hier vermutlich die beste Wahl:

    std::vector<std::unique_ptr<Actions::Action>> actionStack;
    

    Ansonsten ist vielleicht auch boost::ptr_vector interessant für dich.

    3. Du solltest den Destruktor von Action virtual machen, ansonsten kann es zu Memory-Leaks kommen.

    Dazu kommen noch ein paar stilistische Sachen:

    4. Leere Konstruktoren und Destruktoren sollte man weglassen, außer wenn man den Destruktor virtual machen oder den Standard-Konstruktor parallel zu anderen anbieten möchte.

    5. Das void in der Parameterliste schreibt man in C++ üblicherweise nicht, das stammt noch aus C.

    Ansonsten wirst du vielleicht gemerkt haben, dass C++ trotz ähnlicher Syntax andere Konzepte als PHP hat. Und wenn man wie in deinem Fall einfach bestehendes übernimmt, macht man leicht Fehler. Deshalb rate ich dir, erstmal ein C++-Buch zu lesen, welches in die C++-Eigenheiten einführt. Buchempfehlungen findest du im Forum, z.B. in der Signatur von SeppJ.

    Edit: Oh Gott, viel zu spät 😮



  • Skym0sh0 schrieb:

    -.- ja das ist eine inkonsistens, aber mir durchaus bewusst

    Ist überhaupt nicht inkonsistent, sondern verhält sich wie die Default-Sichtbarkeit der Member.

    Skym0sh0 schrieb:

    wichtig ist beim destruktor erstmal das virtual in vererbungsdingen

    Ne, so vage formuliert ist das eben irreführend. Vererbung impliziert keine Polymorphie, das automatische Virtuell-Machen sämtlicher Basisklassendestruktoren zeigt nur, dass man sich nicht genau überlegt, welche Klassen tatsächlich polymorph benutzt und zerstört werden.

    ipsec schrieb:

    Edit: Oh Gott, viel zu spät 😮

    Ist schon gut, du hast einige wichtige Punkte aufgezählt, die vorher noch nicht erwähnt wurden.



  • Nexus schrieb:

    Skym0sh0 schrieb:

    -.- ja das ist eine inkonsistens, aber mir durchaus bewusst

    Ist überhaupt nicht inkonsistent, sondern verhält sich wie die Default-Sichtbarkeit der Member.

    hä?
    das verstehe ich jetzt nicht.

    struct A
    {
        int a; // public, default mäßig
    };
    
    class B
    {
        int a; // private per default
    };
    

    wo ist das konsistent?
    klar, es ist so definiert, man weiss es, ich schreibe auch eh immer den sichtbarkeits modifier dran. aber konsistent ist es für mich nicht, oder wie meinst du das?



  • @ipsec
    Ja es stimmt, ich mache sicherlich Fehler. Mit einem Buch komme ich aber nicht weit, da ich so einfach nicht gut lerne. Ich schreibe dann die Übungen richtig ab und bilde mir ein, es verstanden zu haben. In der Anwendung ist es dann aber immer so eine Sache.. Dazu sind gute Bücher meistens nicht besonders günstig und schnell veraltet. Ich weiß noch gar nicht, ob ich bei C++ bleibe, oder ob ich C#.NET weiter mache, welches mir bis jetzt am Besten gefällt. Kommt auch darauf an, was ich nach meiner Ausbildung machen möchte. Ziel ist erstmal einen generellen Überblick über die Möglichkeiten zu bekommen.

    Ich setz mich lieber an ein Projekt und versuche das umzusetzen. Das dauert am Anfang sicherlich länger, weil ich eben viel falsch mache. Aber ich kann mir dann viel besser merken was und vor allem WARUM ich etwas falsch gemacht habe.

    Wenn ich einen gewissen Status in meinem Projekt erreicht habe, werde ich einen Kollegen um ein CodeReview bitten und so vielleicht noch das ein oder andere korrigieren. Dann habe ich es mir aber auch gemerkt (im Sinne von: "Moment mal, so habe ich das beim letzten mal schon gemacht und es war nicht schön, ich sollte es aus dem und dem Grund so und so machen").



  • Skym0sh0 schrieb:

    wo ist das konsistent?
    klar, es ist so definiert, man weiss es, ich schreibe auch eh immer den sichtbarkeits modifier dran. aber konsistent ist es für mich nicht, oder wie meinst du das?

    Konsistent daran ist, dass die Vererbung in structs und class genau den Default-Sichtbarkeiten entspricht. Inkonsistent wäre es dann, wenn struct standardmäßig trotzdem private erbt 😉



  • Skym0sh0 schrieb:

    aber konsistent ist es für mich nicht, oder wie meinst du das?

    Es ist insofern konsistent, als Default-Sichtbarkeit für Member und für Basisklassen bei einem Schlüsselwort gleich sind.

    Die Unterschiede von struct und class würde ich nicht inkonsistent nennen. "Konsistent" würde nach deiner Definition heissen, dass beide Schlüsselwörter genau gleich wären, wodurch class überflüssig würde.

    trialgod schrieb:

    Ich setz mich lieber an ein Projekt und versuche das umzusetzen. Das dauert am Anfang sicherlich länger, weil ich eben viel falsch mache. Aber ich kann mir dann viel besser merken was und vor allem WARUM ich etwas falsch gemacht habe.

    Das ist zwar grundsätzlich keine schlechte Idee, nur bekommst du in C++ ohne fundiertes Basiswissen sehr schnell Probleme. Trial & Error kannst du vergessen, viele wichtige Themen erfährst du ohne ein gutes Buch gar nie. Auch Internettutorials und Kollegen sind diesbezüglich meist schlechte Quellen...



  • trialgod schrieb:

    Ja es stimmt, ich mache sicherlich Fehler. Mit einem Buch komme ich aber nicht weit, da ich so einfach nicht gut lerne. Ich schreibe dann die Übungen richtig ab und bilde mir ein, es verstanden zu haben.

    Du Sollst die Übungen ja nicht abschreiben sondern selber machen 😉

    trialgod schrieb:

    Ich weiß noch gar nicht, ob ich bei C++ bleibe, oder ob ich C#.NET weiter mache, welches mir bis jetzt am Besten gefällt. Kommt auch darauf an, was ich nach meiner Ausbildung machen möchte. Ziel ist erstmal einen generellen Überblick über die Möglichkeiten zu bekommen.

    Dann guck dir einfach die Zahlreichen Online-Tutorials an.
    Links für Neulinge
    aber halt bloß abstand vom Galileo-Verlag - jedenfalls was C++ angeht :p



  • trialgod schrieb:

    Ich bin rel. neu in C++ und komme aus der PHP-Welt, also bitte Nachsicht, wenn ich etwas mit den Typen oder OOP-Sachen, die es da nicht gibt nicht sofort richtig erfasst habe 😉

    Willkommen! 🙂

    C++ ist übrigens mehr als "C mit OOP". Und ein schlaues Buch zu C++ ist fast immer eine gute Idee, auch wenn du nur reinschnuppern willst. Man muss nicht für alles eine Klassenhierarchie bauen. Und man sollte sich frühst möglich mit dem vertraut machen, was hinter "RAII" steht.



  • Nexus schrieb:

    Private Vererbung benutzt man übrigens sehr selten -- meistens ist Aggregation die bessere Alternative.

    Ich glaube, du meinst wohl eher Komposition. Wie dem auch sei... Ich finde, man sollte private Vererbung und Komposition nicht auf dieselbe Schiene setzen. Private Vererbung heißt ja auch nicht umsonst is-implemented-in-terms-of und Komposition has-a .


Anmelden zum Antworten