Problem mit Software Architektur (C++)



  • @jokester
    Ja diesen Artikel kenne ich mittlerweile auch (seit gestern 17:08) als das erste mal der Begriff "Virtuell Erben" gefallen ist 😉

    Aber ist denn virtuelle Vererbung von Klassen, welche ausschliesslich pure virtuelle Methoden beinhaltet nicht mit den C# und Java interfaces identisch?


  • Administrator

    Selfquote:

    Dravere schrieb:

    Übrigens: Wieso gibst du bei GetName das std::string Objekt als Zeiger zurück? Ist auch einer der Indikatoren, dass du anscheinend ziemlich viel mit new anlegst.

    Würde mich noch interessieren 😉

    Ishildur schrieb:

    Ich denke, dafür is virtuelle Verwebung da, damit die Methode GetName nicht doppeldeutig ist. Ich will ja nicht, dass MyObjekt dem Logger und dem Skriper zwei unterschiedliche Namen zurückgibt.

    Du hast virtual Vererbung definitiv nicht verstanden. Eine virtual Vererbung geschieht auf der Ebene der Klasse/Objekt. Mit Methoden aus zwei unterschiedlichen Klassen hat das nichts zu tun. Bei deinem Beispiel kannst du virtual auch gleich weglassen bei der Vererbung.

    Wenn du zwei Methoden mit gleichen Namen aus unterschiedlichen Klassen hast, welche auch eine Implementation aufweisen (also nicht pure virtual sind), dann hilft auch die virtual Vererbung nichts mehr. Beim Aufruf einer solchen Methode, musst du dann explizit angeben, welche du aufrufen möchtest.

    Ishildur schrieb:

    Sie ist doch abstract 😉

    Also hat sie members, welche (mit grosser Wahrscheinlichkeit) von der alternativen Implementierung nicht benötigt werden 😉

    Und mit welcher Wahrscheinlichkeit tritt dieser Fall auf?

    Grüssli



  • Ishildur schrieb:

    Sie ist doch abstract 😉

    Also hat sie members, welche (mit grosser Wahrscheinlichkeit) von der alternativen Implementierung nicht benötigt werden 😉

    Verstehe ich nicht. Welche Member sollte sie denn haben? Kann mir nicht vorstellen dass das oft vorkommt - also bei mir zB noch nie.

    Weil du dann ja recht schnell konkret wirst und nicht mehr abstrakt bist...

    worum es aber eigentlich geht: dein code sieht wie java code und nicht wie c++ code aus.



  • @Shade Of Mine
    Hahaha, in den Java Foren jammern sie, mein Code sehe wie C/C++ Code aus :p



  • brigens: Wieso gibst du bei GetName das std::string Objekt als Zeiger zurück? Ist auch einer der Indikatoren, dass du anscheinend ziemlich viel mit new anlegst.
    

    Nein ich will nur nicht, dass der string jedes Mal kopiert wird, wenn ich einen Namen abfrage 😉



  • Ishildur schrieb:

    Aber ist denn virtuelle Vererbung von Klassen, welche ausschliesslich pure virtuelle Methoden beinhaltet nicht mit den C# und Java interfaces identisch?

    Hat nichts miteinander zu tun. C++ virtual vererbung ist wirklich nur fuer den deadly diamond.


  • Administrator

    Ishildur schrieb:

    @Shade Of Mine
    Hahaha, in den Java Foren jammern sie, mein Code sehe wie C/C++ Code aus :p

    Spricht nicht gegen die Aussage von Shade Of Mine. Kann gut sein, dass du ein Stil für C++ und Java anwendest, was definitiv falsch ist. Man muss für jede Sprache anders programmieren. Oder du programmierst in Java wirklich wie in C++ und in C++ wie in Java. Dann solltest du auf beides mal ein std::swap anwenden 😉

    Grüssli


  • Mod

    Ishildur schrieb:

    brigens: Wieso gibst du bei GetName das std::string Objekt als Zeiger zurück? Ist auch einer der Indikatoren, dass du anscheinend ziemlich viel mit new anlegst.
    

    Nein ich will nur nicht, dass der string jedes Mal kopiert wird, wenn ich einen Namen abfrage 😉

    Dafür benutzt man eigentlich Referenzen...



  • std::swap

    😃



  • Nein, jetzt bitte nicht noch eine Diskussion ob und wann nun Zeiger oder Referenzen sinnvoller sind :p


  • Administrator

    Ishildur schrieb:

    brigens: Wieso gibst du bei GetName das std::string Objekt als Zeiger zurück? Ist auch einer der Indikatoren, dass du anscheinend ziemlich viel mit new anlegst.
    

    Nein ich will nur nicht, dass der string jedes Mal kopiert wird, wenn ich einen Namen abfrage 😉

    Schon mal davon gehört, dass man Referenzen auf konstante Objekte zurückgeben kann?

    class MyObject
    {
    private:
      std::string m_name;
    
    public:
      std::string const& getName() { return m_name; }
    };
    

    Und schon findet keine Kopie satt. Zudem verwenden gewisse Bibliotheken bei std::string COW (Copy-On-Write). Und nicht zuletzt, ist es recht fragwürdig, wie stark diese Kopie wirklich ins Gewicht der Performance fällt, da ich mal vermutet, dass du es deswegen nicht machen möchtest.

    Zudem, du gibst immer einen Zeiger auf ein nicht-konstantes Objekt zurück, wodurch man den Namen von Aussen verändern kann. Bye Bye Kapselung ...

    Grüssli

    PS: Ich ziehe mich vorerst zurück. Muss noch ein paar Schnittstellenspezifikationen erstellen, dieser Thread geht mir gerade ein wenig zu schnell vorwärts 😉



  • @Dravere
    Ja ich werde mich jetzt einmal umfassend mit dem Thema Mehrfachvererbung auseinandersetzten bevor ich nochmal ins Messer laufe 😉 Vielen Dank an alle für die vielen Tips in diesem Thread!



  • Ishildur schrieb:

    @Shade Of Mine
    Hahaha, in den Java Foren jammern sie, mein Code sehe wie C/C++ Code aus :p

    Hast du einen Link dazu? Würde mich einfach nur interessieren was Java Programmierer darunter verstehen.


  • Mod

    Shade Of Mine schrieb:

    Ishildur schrieb:

    @Shade Of Mine
    Hahaha, in den Java Foren jammern sie, mein Code sehe wie C/C++ Code aus :p

    Hast du einen Link dazu? Würde mich einfach nur interessieren was Java Programmierer darunter verstehen.

    http://www.ibm.com/developerworks/java/library/j-noaccent.html



  • SeppJ schrieb:

    Shade Of Mine schrieb:

    Ishildur schrieb:

    @Shade Of Mine
    Hahaha, in den Java Foren jammern sie, mein Code sehe wie C/C++ Code aus :p

    Hast du einen Link dazu? Würde mich einfach nur interessieren was Java Programmierer darunter verstehen.

    http://www.ibm.com/developerworks/java/library/j-noaccent.html

    Das geht leider nur auf C ein... 😕


  • Mod

    Shade Of Mine schrieb:

    SeppJ schrieb:

    Shade Of Mine schrieb:

    Ishildur schrieb:

    @Shade Of Mine
    Hahaha, in den Java Foren jammern sie, mein Code sehe wie C/C++ Code aus :p

    Hast du einen Link dazu? Würde mich einfach nur interessieren was Java Programmierer darunter verstehen.

    http://www.ibm.com/developerworks/java/library/j-noaccent.html

    Das geht leider nur auf C ein... 😕

    Die letzten paar Punkte sind C++ und ein paar der C Punkte treffen auch auf C++ zu. Aber insgesamt sind es eher Kleinigkeiten. Vermutlich meinen die Leute in Ishildurs Java-Forum noch viel stärkere Stilunterschiede. So wie man hier ehemalige Java-Programmierer daran erkennt, dass sie alles auf den Heap legen. Wobei das umgekehrt in Java natürlich nicht geht, einen C++ Programmierer an der Stack-Nutzung zu erkennen. Eventuell ist gemeint, dass C++ Programmierer in Java hinter sich sauber aufräumen, anstatt sich auf die Garbage-Collection zu verlassen.



  • @Shade of Mine

    Hast du einen Link dazu?

    Hehe das war nicht so ernst gemeint 😉

    Es war eher so eine Anspielung darauf, dass jemand der viele Sprachen kennt (wenn auch nicht bis ins kleinste technische Detail) schliesslich überall zu hören bekommt, dass er von irgend einer anderen Sprache "verdorben" sein.
    Ich persönlich kenne ein wenig Assembler,C,C++,C#,Java,Delphi,Lisp,SQL sowie zahlreiche Scriptsprachen wie PHP, Javascript, Matlab,Maple usw... Mit "ein wenig kennen" meine ich allerdings nicht, "einmal ein Tutorial gemacht" oder so, sondern damit mindest. ein halbes Jahr gearbeitet. In fast jeder dieser Sprachen habe ich interessante und zunächst zwar oft fremdartige, jedoch elegante Ansätze zur Lösung von Problemen gesehen und schliesslich Wege gesucht, diese neu gewonnenen Konzepte in zukünftigen Projekten auch in anderen Sprachen umzusetzen, was bei den entsprechenden Szeneleuten eigentlich selten gut ankommt.

    Ich habe bspw. während der Berufslehre ein Jahr lang ein Praktikum als Delphi Entwickler gemacht. Die sind mir regelrecht an die Gurgel gegangen, als ich da anfing mit Vererbung zu arbeiten (Ich war eben "verdorben" durch meinen Umgang mit C/C++), und selbst als ich anhand von Beispielen zeigen konnte, wie elegant man damit gewisse Sachen lösen kann, wollte einfach niemand etwas davon hören (Man würde ja vom Meister zum Schüler werden). Delphi ist zwar Objektorientiert, jedoch wurde dieses Feature in dieser Firma eigentlich nie verwendet, man verwendetete fast auschliesslich HasA und keine IsA Beziehungen. Als ich einem Java Professor an unserer Uni Bitmasken näherbringen wolle, verdrehte er nur die Augen und benutzt lieber eine ArrayList mit 20 Booleans und 20 Setter und Getter Methoden. Eine Bitmaske ist total LowLevel und so...
    Unser Lisp Professor behauptet, dass rein funktionale Konzepte (ausschliesslich Substitution, keine States) auf jeden Fall und immer besser und vor allem eleganter seien, als eine böse Statemachine (selbst ein von mir geschriebenes C Programm, welches durch dynamische Programmierung O(n) eine grosse Fibonacci Zahl in wenigen ms berechnen konnte, während der "rein funktionale" O(2^n) Approach in Lisp mehrere Stunden dafür benötigte, vermochte nicht zu überzeugen "Rekursiv ist trotzdem eleganter, bessär, eine Statemaschine ist trotzdem böse!!"
    Noch während der Berufslehre hatte ich einen beleidigend einfachen Javatest.
    Die Aufgabe war, eine Liste von Objekten auf eine Reihe von Anforderungen hin zu überprüfen und schliesslich all diejenigen Objekte, welche sämtliche Anforderungen erfüllten auf den Bildschirm auszugeben. Ich schrieb das etwa so:

    while HasNext begin
    if not Anforderung1 then continue;
    if not Anforderung2 then continue;
    if not Anforderung2 then continue;
    print Element
    end

    Das gabe ein "Ungenügend", das sei keine "strukturierte Programmierung", sonst solle ich ihm das mal in einem PAP oder in einem Nassi-Shneiderman darstellen.
    Korrekt wäre gewesen:

    boolean b1
    boolean b2
    boolean b3

    while HasNext begin
     b1 = false
     b2 = false
     b3 = false
    
     if Anforderung1 then b1 = true
     if Anforderung2 then b2 = true
     if Anforderung2 then b3 = true
    
     if b1 == true and b2 == true and b3 == true then print Element 
    end
    

    Auch die Argumentation dass es doch IMHO keinen Sinn macht, die letzten 2 Eigenschaften zu überprüfen, wenn bereits die erste nicht erfüllt ist, war nicht von interesse, es musste einfach "strukturierte Programmierung" sein, alles Andere war falsch (böse)!

    Das meinte ich damit, dass man als Allrounder eigentlich in jedem Forum irgendwann gegen eine Wand läuft 😉

    Ich persönlich finde, jeder der mal Assembler programmiert hat, programmiert anschliessend anders C, jeder der schon mal Java programmiert hat, programmiert anschliessend anders C++, jeder der schon mal C++ programmiert hat, programmiert anschliessend auch anders Java usw...



  • @SeppJ

    dass C++ Programmierer in Java hinter sich sauber aufräumen, anstatt sich auf die Garbage-Collection zu verlassen.

    Hehe, ja in einem PHP Forum wurde ich mal zur Schnecke gemacht, weil ich ein Image Handles explizit freigegeben habe, nachdem ich es nicht mehr benutzt habe, anstatt dies vom Script automatisch erledigen zu lassen.

    Und stimmt jetzt fällt mir wieder das eine oder andere ein. In einem XNA Forum (Ich programmierte ein xbox 360 Spiel mit C# und XNA als Projektarbeit im 4. Semester) hatte ich die Frechheit, mich nach Referenz Counting im Resourcen Manager zu erkundigen. Da hiess es, ich solle endlich aufhören so komplett veraltete Konzepte zu verfolgen, das brauche heutzutage niemand mehr, dafür sei der Garbage Collector da, es müsse endlich ein Umdenken stattfinden usw...



  • Habe übrigens noch gerade ein IMHO gutes Beispiel, warum Interfaces keine member variablen haben sollten:

    class IVideoService{
    };
    
    class OpenGLVideoService:public IVideoService{
    };
    
    class Direct3DVideoService:public IVideoService{
    };
    

    Wetten der OpenGLVideoService hat nicht dieselben Members wie der Direct3DVideoService? Wetten eine Direct3D TextureResource hat komplett andere Members als eine OpenGl TextureResource?



  • Ishildur schrieb:

    Noch während der Berufslehre hatte ich einen beleidigend einfachen Javatest.
    Die Aufgabe war, eine Liste von Objekten auf eine Reihe von Anforderungen hin zu überprüfen und schliesslich all diejenigen Objekte, welche sämtliche Anforderungen erfüllten auf den Bildschirm auszugeben. Ich schrieb das etwa so:

    while HasNext begin
    if not Anforderung1 then continue;
    if not Anforderung2 then continue;
    if not Anforderung2 then continue;
    print Element
    end

    Das gabe ein "Ungenügend", das sei keine "strukturierte Programmierung", sonst solle ich ihm das mal in einem PAP oder in einem Nassi-Shneiderman darstellen.
    Korrekt wäre gewesen:

    boolean b1
    boolean b2
    boolean b3

    while HasNext begin
     b1 = false
     b2 = false
     b3 = false
    
     if Anforderung1 then b1 = true
     if Anforderung2 then b2 = true
     if Anforderung2 then b3 = true
     
     if b1 == true and b2 == true and b3 == true then print Element 
    end
    

    Auch die Argumentation dass es doch IMHO keinen Sinn macht, die letzten 2 Eigenschaften zu überprüfen, wenn bereits die erste nicht erfüllt ist, war nicht von interesse, es musste einfach "strukturierte Programmierung" sein, alles Andere war falsch (böse)!

    Besser:

    while hasNext
    begin
      if (Anforderung1) and (Anforderung2) and (Anforderun3)
        print Element
    end
    

    Keine ekligen continues.


Anmelden zum Antworten