Erstes OOP Projekt - Erschaffung einer Instanz namens Person - gelöst



  • Belli schrieb:

    1. was ist denn getGroeße?
    2. warum heißt es nicht getGröße?

    Ich habe es halt so geschrieben... läuft doch auf das Gleiche hinaus...



  • [Rewind] schrieb:

    Du hast schon mal das Prinzip von Gettern verstanden (vllt. sogar auch von Settern). Deine Member sind aber trotzdem nicht initialisiert (zumindest nicht über die Initialisierungsliste, die mehr als empfehlenswert ist). Noch ein Tipp: meide Sonderzeichen wie Umlaute in Namen deiner Variablen, Funktionen, etc.

    Hey Rewind... wie hast Du das gestern gemeint mit "Member sind aber trotzdem nicht initialisiert"?? Wie soll bzw. kann ich denn einen String initialisieren??



  • silent_max schrieb:

    Belli schrieb:

    1. was ist denn getGroeße?
    2. warum heißt es nicht getGröße?

    Ich habe es halt so geschrieben... läuft doch auf das Gleiche hinaus...

    Obwohl ich lieber anfangen würde englische Begriffe zu benutzen.

    getGroeße und getGröße sind immer noch Sonderzeichen.

    Besser wäre doch getHeight und setHeight 😉

    Für die Namengebung der Dateien, benutze keine Leerzeichen.

    Benutze am besten den Klassennamen für die Dateien,in deinem Fall wäre dies Person.h und Person.cpp.

    Initialisieren, kann sie mit der Initialisierungsliste

    Person::Person():Vorname(""),
                     Nachname(""),
                     Haarfarbe(""),
                     Augenfarbe(""),
                     groesse(0)
    {}
    


  • demonking schrieb:

    Person::Person():Vorname(""),
                     Nachname(""),
                     Haarfarbe(""),
                     Augenfarbe(""),
                     groesse(0)
    {}
    

    mach mal lieber:

    Person::Person():groesse(0){}
    


  • demonking schrieb:

    Initialisieren, kann sie mit der Initialisierungsliste

    Person::Person():Vorname(""),
                     Nachname(""),
                     Haarfarbe(""),
                     Augenfarbe(""),
                     groesse(0)
    {}
    

    Wo muss ich denn die Initialisierungsliste machen?? In der Header-Datei oder in CPP-Datei? Und wo? Nach dem Quellcode??

    Gruß

    Max



  • @silent_max

    1. Was ist diner Meinung nach zwischen diesen beiden Zeilen anders, so dass deine IDE das eine Unterkringelt, das andere Nicht?

    cin  >> Passant.getHaarfarbe();
      cin  >> Passant.getGroeße;
    

    was meinst du, was

    string getHaarfarbe()
    {
       return Haarfarbe;
    };
    

    macht?
    Also jetzt mal so ganz genau. Nicht nur so in etwa. Und dann erkläre mir, warum

    cin  >> Passant.getHaarfarbe();
    

    funktioniert



  • otze schrieb:

    @silent_max

    1. Was ist diner Meinung nach zwischen diesen beiden Zeilen anders, so dass deine IDE das eine Unterkringelt, das andere Nicht?

    cin  >> Passant.getHaarfarbe();
      cin  >> Passant.getGroeße;
    

    Ja die beiden Klammern fehlen. Sorry, habe ich nicht (mehr) gesehen. Das blöde ist nur, dass der >> Operand immer noch rot unterringelt ist.

    otze schrieb:

    was meinst du, was

    string getHaarfarbe()
    {
       return Haarfarbe;
    };
    

    macht?
    Also jetzt mal so ganz genau. Nicht nur so in etwa.

    Die als string deklarierte Methode gibt einen string zurück würde ich jetzt mal sagen.

    otze schrieb:

    Und dann erkläre mir, warum

    cin  >> Passant.getHaarfarbe();
    

    funktioniert

    Da hast Du mich auf dem falschen Fuß erwischt, ich kann es nicht erklären.



  • Da musst Du Dich nicht wundern, es funktioniert nämlich nicht ...



  • Es funktioniert nicht, das stimmt, aber es kompiliert. Und warum kompiliert es?



  • Mit dem Getter erhälst du eine temporäre Kopie des String-Objekts (d.h. des Attributs), wo der aus dem Stream extrahierte Wert landet. Da aber das Objekt und damit auch die Eingabe gleich danach zerstört werden, ändert sich innerhalb deines Objektes nichts. Max, lies doch bitte was über Setter nach. ⚠



  • [Rewind] schrieb:

    Da aber das Objekt und damit auch die Eingabe gleich danach zerstört werden, ändert sich innerhalb deines Objektes nichts.

    Nein, es ändert sich innerhalb des Objekts nichts, weil das Innere des Objekts überhaupt nicht (verändernd) angesprochen wird.



  • freakC++ schrieb:

    Aber nur, wenn er keine Ahnung von Software Engineering hat.

    Argh. Ich rede nun ja wirklich nicht gerne Off-Topic, aber das ist eine ziemlich schlechte Verallgemeinerung (die eigentlich nur von jemandem kommen sollte, der keine Ahnung von Software Engineering hat :P). Für public-Attribute gibt es manchmal sehr gute Gründe die keine wirklichen Nachteile mit sich ziehen wenn man sie gut anwendet. Und nicht auf dem Level von "goto hat auch gute Anwendungsfälle" sondern schon wirklich gute.

    Außerdem sind viele Setter (wenn sie was anderes machen als Dependency-Injection) ein Zeichen von schlechtem Klassendesign (wozu braucht die Außenwelt ständig Schreibzugriffe auf deine privaten Daten?)



  • TravisG schrieb:

    Für public-Attribute gibt es manchmal sehr gute Gründe die keine wirklichen Nachteile mit sich ziehen wenn man sie gut anwendet. Und nicht auf dem Level von "goto hat auch gute Anwendungsfälle" sondern schon wirklich gute.

    Beispiel bitte!

    TravisG schrieb:

    Außerdem sind viele Setter (wenn sie was anderes machen als Dependency-Injection) ein Zeichen von schlechtem Klassendesign (wozu braucht die Außenwelt ständig Schreibzugriffe auf deine privaten Daten?)

    Dependency-Injection?



  • TravisG schrieb:

    Außerdem sind viele Setter (wenn sie was anderes machen als Dependency-Injection) ein Zeichen von schlechtem Klassendesign (wozu braucht die Außenwelt ständig Schreibzugriffe auf deine privaten Daten?)

    Ist es besser, einfach unkontrollierten Zugriff auf die Daten zu erlauben? Schon sehr viele Probleme damit in altem Code gesehen, und man konnte nicht mal einen Breakpoint setzen. Außerdem verbirgt ein Setter Implementierungsdetails und ist einem public Member fast immer vorzuziehen, außer es geht vielleicht um extrem performancekritische Fälle.



  • volkard schrieb:

    TravisG schrieb:

    Für public-Attribute gibt es manchmal sehr gute Gründe die keine wirklichen Nachteile mit sich ziehen wenn man sie gut anwendet. Und nicht auf dem Level von "goto hat auch gute Anwendungsfälle" sondern schon wirklich gute.

    Beispiel bitte!

    Generell kann man sagen, dass es einige Anwendungsfälle gibt bei denen sich die Zugriffssemantik der dahinterliegenden Daten niemals ändert (der eigentlich Sinn von Getter-Methoden: man kann die Semantik des Datenzugriffs mit minimalen Codeänderungen umbiegen). Ein einfaches Beispiel, dass wahrscheinlich jedem mal über den Weg läuft wenn er mit GUIs oder Grafikprogrammierung zu tun hat:

    struct Vector2 //oder: struct Point
    {
      float x,y;
    }
    

    Getter würden hier einfach keinerlei Vorteile bieten. Public hat dagegen einfach den Vorteil, dass es Code schrumpfen lässt und die Finger deutlich weniger beansprucht. Vergleiche:

    float dot(const Vector2 &a, const Vector2 &b)
    {
      return a.x * b.x + a.y * b.y;
    }
    
    float dot(const Vector2 &a, const Vector2 &b)
    {
      return a.getX() * b.getX() + a.getY() * b.getY();
    }
    

    Selbst bei diesem trivialen Beispiel erzeugen die zusätzlichen Klammern für mich eine kleine Unterbrechung des Leseflusses. Vielleicht geht es dir nicht so, aber da es mir so geht solltest du davon ausgehen, dass es auch noch andere gibt denen es ähnlich geht. Und das ist ein ziemlich einfaches Beispiel. In einer Codesektion, in der sehr viel auf die beiden Attribute zugegriffen wird, trägt das durchaus dazu bei die Übersicht zu verhindern (ich habe mit Java-Codebasen gearbeitet, wo hier wirklich getX() und getY() verwendet wurde, und das hat gewisse Codesektionen einfach massiv aufgebläht).

    Warum also die längere Variante nehmen, wenn sie einfach keine Vorteile hat?

    Generell sind "plain old data" Typen gute Kandidaten für Konstrukte mit öffentlichen Attributen.

    Volkard schrieb:

    TravisG schrieb:

    Außerdem sind viele Setter (wenn sie was anderes machen als Dependency-Injection) ein Zeichen von schlechtem Klassendesign (wozu braucht die Außenwelt ständig Schreibzugriffe auf deine privaten Daten?)

    Dependency-Injection?

    http://en.wikipedia.org/wiki/Dependency_injection



  • TravisG schrieb:

    Volkard schrieb:

    TravisG schrieb:

    Außerdem sind viele Setter (wenn sie was anderes machen als Dependency-Injection) ein Zeichen von schlechtem Klassendesign (wozu braucht die Außenwelt ständig Schreibzugriffe auf deine privaten Daten?)

    Dependency-Injection?

    http://en.wikipedia.org/wiki/Dependency_injection

    Verstehe ich nicht. Ist das eine Java-Technik? Ist sie in C++ relevant?



  • TravisG schrieb:

    volkard schrieb:

    TravisG schrieb:

    Für public-Attribute gibt es manchmal sehr gute Gründe die keine wirklichen Nachteile mit sich ziehen wenn man sie gut anwendet. Und nicht auf dem Level von "goto hat auch gute Anwendungsfälle" sondern schon wirklich gute.

    Beispiel bitte!

    Generell kann man sagen, dass es einige Anwendungsfälle gibt bei denen sich die Zugriffssemantik der dahinterliegenden Daten niemals ändert (der eigentlich Sinn von Getter-Methoden: man kann die Semantik des Datenzugriffs mit minimalen Codeänderungen umbiegen). Ein einfaches Beispiel, dass wahrscheinlich jedem mal über den Weg läuft wenn er mit GUIs oder Grafikprogrammierung zu tun hat:

    struct Vector2 //oder: struct Point
    {
      float x,y;
    }
    

    Getter würden hier einfach keinerlei Vorteile bieten. Public hat dagegen einfach den Vorteil, dass es Code schrumpfen lässt und die Finger deutlich weniger beansprucht. Vergleiche:

    float dot(const Vector2 &a, const Vector2 &b)
    {
      return a.x * b.x + a.y * b.y;
    }
    
    float dot(const Vector2 &a, const Vector2 &b)
    {
      return a.getX() * b.getX() + a.getY() * b.getY();
    }
    

    Selbst bei diesem trivialen Beispiel erzeugen die zusätzlichen Klammern für mich eine kleine Unterbrechung des Leseflusses. Vielleicht geht es dir nicht so, aber da es mir so geht solltest du davon ausgehen, dass es auch noch andere gibt denen es ähnlich geht. Und das ist ein ziemlich einfaches Beispiel. In einer Codesektion, in der sehr viel auf die beiden Attribute zugegriffen wird, trägt das durchaus dazu bei die Übersicht zu verhindern (ich habe mit Java-Codebasen gearbeitet, wo hier wirklich getX() und getY() verwendet wurde, und das hat gewisse Codesektionen einfach massiv aufgebläht).

    Warum also die längere Variante nehmen, wenn sie einfach keine Vorteile hat?

    Generell sind "plain old data" Typen gute Kandidaten für Konstrukte mit öffentlichen Attributen.

    Jo, da teile ich Deine Meinung.



  • volkard schrieb:

    TravisG schrieb:

    Volkard schrieb:

    TravisG schrieb:

    Außerdem sind viele Setter (wenn sie was anderes machen als Dependency-Injection) ein Zeichen von schlechtem Klassendesign (wozu braucht die Außenwelt ständig Schreibzugriffe auf deine privaten Daten?)

    Dependency-Injection?

    http://en.wikipedia.org/wiki/Dependency_injection

    Verstehe ich nicht. Ist das eine Java-Technik? Ist sie in C++ relevant?

    Hmm... du verstehst es bestimmt, kennst es aber nicht unter dem Namen. Der Begriff ist mit Sicherheit ein Java-Buzzword, und ich verwende ihn nun auch da die meisten Neuprogrammierer das Konzept darunter kennelernen 🤡 .

    Im Prinzip gehts einfach darum bestimmte Aufgaben in einer Softwarekomponente austauschbar zu machen (dadurch löst man harte Abhängigkeiten auf). Z.B. könntest du dir eine Klasse vorstellen, die einen Datensatz an Personen verwaltet und dir anbietet, nach Personen per Namen zu suchen. Dazu muss die Implementierung zwangsweise irgendeinen Suchalgorithmus benutzen. Die Klasse PersonenVerwaltung hat dann intern nur einen Zeiger auf eine abstrakte Basisklasse mit dem Namen "SpeicherUndSortierAlgorithmus" hinter dem sich dann DoofSpeichernUndLinearSuchen, BinärBaumSpeicherUndBinärbaumSuche, etc. verbergen.

    Die "Dependency-Injection" ist dann einfach die Methode setzeSortierUndSpeicherAlgorithmus(SpeicherUndSortierAlgorithmus *konkreteImplementation) mit der man die konkrete Implementierung (dependency) setzen (inject) kann.

    Das ist eigentlich das klassische Beispiel für das Strategy-Pattern, aber dependency injection ist einfach so ein Regenschirmbegriff für alles, dass Abhängigkeiten austauschbar macht (z.B. Strategy-Pattern, oder Component-Pattern, etc.).



  • Der Begriff Dependency Injection (DI) bzw. Inverse of Control (IoC) wird z.B. auch in C# benutzt.
    Es ermöglicht besonders, einzelne Klassen und Methoden besser testen zu können, indem Abhängigkeiten zu externen Klassen (z.B. externe Ressourcenzugriffe, Logger, ...) durch Schnittstellen ersetzt werden, so daß diese durch (dummy) Mock-Implemenationen ersetzt werden (d.h. es wird nur die Funktionalität der eigentlich zu testenden Methode betrachtet).
    Beim Test Driven Design (TDD) ist damit DI quasi fest vorgegeben.

    Dies Begriffe sollten also jedem Informatiker bekannt sein...



  • Th69 schrieb:

    Dies Begriffe sollten also jedem Informatiker bekannt sein...

    JA ! Dann bin ich ja doch nicht ganz doof 😃


Anmelden zum Antworten