Performancemythen?



  • Xin schrieb:

    Wenn Du Respekt willst, schreib doch etwas, was man ernstnehmen kann.

    Wenn du Respekt willst, lern mal über den Tellerrand zu schauen und vielleicht sogar, was Multimethoden sind.

    (Da ich keinen Respekt will kann ich hier wunderbar rummeckern.)



  • C++ 5-10mal langsamer als C.
    Plattformunabhängiger Assembler.
    Nutzt man OOP bei Funktionsrufen, wo keine Entscheidungen zu treffen sind, so verliert man Zeit.

    Bitte Xin, werd kein Informatiklehrer/professor. Schreib keine Bücher. Behalt deine "Weisheiten" für dich. Wir haben schon genug IT-Verbrechen wie libxml. Danke.



  • Wird eigentlich irgendjemand hier pro Buchstabe bezahlt ?
    Kann es sein, dass irgendjemand "OO (nicht) ist langsamer" als Performancemythos dargestellt hat und anschließend 20 Seiten über die Definition von OO und später über Sprachvorteile gestritten hat (was ein prima Themen für eigene Threads wären).

    Mein Vorschlag: Lasst uns doch mal stichwortartig die bisher entdeckten/vermuteten Performancemythen auflisten.

    Ich fang' mal an:
    - "OO ist (nicht) schlecht für Performance"
    - "Die Ordnung eines Algorithmus' ist nicht das einzige Bewertungskriterium für die Performance"
    - ...

    Was fällt Euch noch auf ?

    Gruß,

    Simon2.



  • @DEvent:
    call mal bitte basisklasse::mach_was aus der "abgeleiteten" klasse 😉
    Das ist keine vererbung, das ist object cloning. du hast dort btw auch keine virtuellen funktionen auf die Xin so steht 😉

    Xin schrieb:

    Die Frage 1: Ich programmiere kein Lisp, ich kann dazu keine brauchbare Meinung vertreten. Ich habe mal Google angeworfen, dort wird LISP nachgesagt, dass es wohl OOP kann. Da ich Lisp nicht programmiere und für die Antwort hier auch nicht mal eben schnell lerne, kann ich dazu aber nichts sagen. Ich sehe aber auch nicht, warum grade LISP hier eine große Rolle spielen sollte.

    OK, das ist der Beweis: du kennst nur C++/Java und baust darauf deine kleine OO Welt auf. Macht also keinen Sinn mehr zu diskutieren. Deshalb kleiner Tip an dich: schau dich mal um welche OO Features andere Sprachen haben. Es ist ein wahnsinnig interessantes Thema. OO ohne Klassen zu programmieren - siehe zB JavaScript. Man kann sich zwar Objekte so hinbiegen dass sie ein bisschen wie Klassen wirken, aber man verliert dadurch soviel was JS einem bieten kann.

    Frage 2: Kommt auf die Implementierung an, ich sehe kein Problem mit Prototypen oder Klonen von Objekten.

    Aber man hat keine virtuellen funktionen.

    Frage 3: Überlade in C++ mal z.B. operator +(). Die ist abhängig von zwei Datentypen. Quasi eine Multimethode. Trotzdem ist operator +() keine virtuelle Methode, sondern poplige Überladung.
    Lass es mich anders ausdrücken. Virtuelle Funktionen sind besser als Multimethoden aus dem gleichen Grund warum Steine besser als Hosen sind. Beides hat nichts miteinander zu tun.

    Geil. Du weisst nicht was multimethoden sind aber versuchst mitzureden 😉
    multimethoden dispatchen zur laufzeit wenn nötig.

    Fragen beantwortet, obwohl sie teils "Warum ist es nachts kälter als draußen?" Charakter haben. Hast Du noch mehr Fragen?

    es waren die essentiellen fragen ob du dich mit OOP auskennst - du hast versagt. danke.

    Die übliche Definition ist also Deiner Aussage nach, dass es nicht genau zu definieren ist. Und damit ist die Mehrzahl dann zufrieden?
    Klasse Definition.

    Exakt. Weil es eine Denkweise und keine technik ist.

    Sprachen neben C++ oder Java machen mir keine bisher Probleme. Mal eben "LISP" einzuwerfen ohne etwas konkretes zu aufzeigen, was meiner Aussage widerspricht, ist dafür etwas wenig.

    multimethoden habe ich eingeworfen die kennst du nicht und prototype sprachen kennst du auch scheinbar nicht. also was willst du? alles was du nicht kennst ignorieren?

    Zumal Du erstmal Deine Definition an C++ belegen darfst - ich erinnere an die immernoch nicht beantwortete Frage von mir.
    Wenn meine Definition auf LISP nicht passen würde, dann wäre das schlecht, aber die "Standard"-Definition passt nichtmals auf C++.

    Und genau das ist der Punkt: eine Sprache ist nicht OO sondern ein Programm. C++ unterstützt OO features wie vererbung, polymorphie aber man muss nicht OO programmieren. in der tat sind die meisten C++ programme nicht rein OO.

    Der Spaß heißt Reflection. Falsche Baustelle.

    Nein, ein sehr relevanter Punkt: wie dynamisch muss Polymorphie sein damit sie polymorphie ist?

    Bei wikipedia wird zB überladung bereits zur polymorphie gezählt. ist es nicht interessant dass deine definition nicht die einzig mögliche ist?

    zumal du ausser C++ und Java nichts kennst - klar auf C++ und Java trifft deine Definition teilweise zu - aber du hast bereits mehrmals von Forengrößen hier gehört, dass sie OOP als eine Denkweise verstehen. Denk mal darüber nach.

    Ich kann dir wirklich nur ans herz legen deinen horizont zu erweitern. Sprachen wie Self und LISP lernen dir ein komplett neues verständnis von OOP. Deshalb verstehst du uns hier auch nicht. Wir sind von dem Klassen denken komplett weg. Und ohne Klassen keine Vererbung und keine virtuellen Funktionen.



  • Xin schrieb:

    Wenn Du als mathematisch geschulter Mensch "schwammig" als mathematisch akzeptabel beschreibst, dann habe ich den Verdacht, dass der recht umfangreiche Anteil Deines Studiums Mathematik dadurch zustande kam, weil Du die Matheschein nie beim erstenmal bekommen hast. Das ist allerdings eine reine Mutmaßung, keine Behauptung.

    War mir fast klar, dass jetzt sowas in der Art kommt. Ich weiß was ich kann. Du bist nicht in der Position das in Frage zu stellen. Dementsprechend ist meine Motivation Dir jetzt irgendwas zu beweisen ziemlich gering. Aber ich kann natürlich meinerseits Vermutungen über Deinen mathematischen Bildungsstand tätigen sowie Deine Erfahrung in logischem Schließen. Über meine Studienleistungen bewahre ich jetzt einfach mal stillschweigen... wäre der Abschluß zu gut, dann bin ich ja völlig unbrauchbar und hab nur auswendig gelernt, ist er zu schlecht bin ich gleich doof. Und notfalls war's halt einfach ne Billiguni. Auf diese Kindereien hab ich einfach keinen Bock.



  • Ich versuch mal eine weniger schwammige definition aufzustellen(ich hab kein mathematisches Studium und bin kein Diplominformatiker, darum: kreuzigt mich nicht).

    Die Objektorientierte Programmierung versucht die Eigenschaften, abhängigkeiten und interaktionsmöglichkeiten von Objekten zu abstrahieren und als programmcode zu modellieren. Die OOP versucht somit, die Denkweise des Menschen direkt als programmcode umzusetzen.

    Ein Objekt ist eine Abstraktion eines Physischen oder logischen Gegenstandes. Objekte zeichnen sich dadurch aus, dass sie Zustände und logische Abhängigkeiten untereinander besitzen. Diese Abhängigkeiten können in Form von Vererbung,Komposition oder Interaktion ausgedrückt werden. Der Zustand eines Objektes ist gekapselt und die kontrolle über ihn obliegt allein dem Objekt.

    //edit hmm lange nicht komplett. schwer zu definieren. wie bringt man zb rein, dass Funktionen als Objekte augefasst werden können oder dass sogar der Programmcode selbst ein Objekt ist?



  • Xin schrieb:

    Wenn Du als mathematisch geschulter Mensch "schwammig" als mathematisch akzeptabel beschreibst, dann habe ich den Verdacht, dass der recht umfangreiche Anteil Deines Studiums Mathematik dadurch zustande kam, weil Du die Matheschein nie beim erstenmal bekommen hast. Das ist allerdings eine reine Mutmaßung, keine Behauptung.

    Dafür bekommst du inf *lol*-Punkte. Echt.



  • Shade Of Mine schrieb:

    Xin schrieb:

    Die Frage 1: Ich programmiere kein Lisp, ich kann dazu keine brauchbare Meinung vertreten. Ich habe mal Google angeworfen, dort wird LISP nachgesagt, dass es wohl OOP kann. Da ich Lisp nicht programmiere und für die Antwort hier auch nicht mal eben schnell lerne, kann ich dazu aber nichts sagen. Ich sehe aber auch nicht, warum grade LISP hier eine große Rolle spielen sollte.

    OK, das ist der Beweis: du kennst nur C++/Java und baust darauf deine kleine OO Welt auf.

    Es beweist, dass ich kein brauchbare Erfahrung in LISP habe, um damit zu argumentieren.

    Shade Of Mine schrieb:

    Macht also keinen Sinn mehr zu diskutieren. Deshalb kleiner Tip an dich: schau dich mal um welche OO Features OO ohne Klassen zu programmieren - siehe zB JavaScript. Man kann sich zwar Objekte so hinbiegen dass sie ein bisschen wie Klassen wirken, aber man verliert dadurch soviel was JS einem bieten kann.

    Ich habe OO in JS programmiert, um SVG Dokumente zu bearbeiten und habe dafür u.a. grafische Elemente programmiert, wie Buttons, Listenwidgets usw.

    Shade Of Mine schrieb:

    Frage 2: Kommt auf die Implementierung an, ich sehe kein Problem mit Prototypen oder Klonen von Objekten.

    Aber man hat keine virtuellen funktionen.

    Wo steht, dass man virtuelle Funktionen oder Klassen für OOP braucht?
    Man braucht eine Methode, um OOP umzusetzen und das geht in C++ in der Regel mit virtuelle Methoden.
    Man könnte auch z.B. Funktionszeiger verwenden. Es reicht jedenfalls nicht "plain classes" zu nehmen.

    Shade Of Mine schrieb:

    Frage 3: Überlade in C++ mal z.B. operator +(). Die ist abhängig von zwei Datentypen. Quasi eine Multimethode. Trotzdem ist operator +() keine virtuelle Methode, sondern poplige Überladung.
    Lass es mich anders ausdrücken. Virtuelle Funktionen sind besser als Multimethoden aus dem gleichen Grund warum Steine besser als Hosen sind. Beides hat nichts miteinander zu tun.

    Geil. Du weisst nicht was multimethoden sind aber versuchst mitzureden 😉
    multimethoden dispatchen zur laufzeit wenn nötig.

    Ich war in dem Moment bei Überladen in etwa der Form:

    bool operator =( BasisObjekt & lhs, BasisObjekt &rhs )
    

    so dass die OO-Möglichkeiten über virtuelle Basisobjekte realisiert würden.
    Mea culpa.

    Wie ich schon zuvor schrieb: sobald man sich irgendwo einen Irrtum erlaubt, wird es als ultimativer Beweis gewertet. Ich seh's positiv: Ich habe sehr viele Antworten geschrieben, ohne mir Fehler zu erlauben.
    Im Verhältnis liege ich damit weiterhin recht gut.

    Shade Of Mine schrieb:

    Die übliche Definition ist also Deiner Aussage nach, dass es nicht genau zu definieren ist. Und damit ist die Mehrzahl dann zufrieden?
    Klasse Definition.

    Exakt. Weil es eine Denkweise und keine technik ist.

    weil...

    Ich lese immer nur Behauptungen und "Du hast nicht recht".

    Shade Of Mine schrieb:

    Und genau das ist der Punkt: eine Sprache ist nicht OO sondern ein Programm. C++ unterstützt OO features wie vererbung, polymorphie aber man muss nicht OO programmieren. in der tat sind die meisten C++ programme nicht rein OO.

    Rein "OO"? Was ist denn reines "OO"?
    Ist das sowas wie "Anfänger OO" und "Experten OO", was ich hier schon lesen musste?
    Entweder ist es "OO" oder nicht "OO".
    Abgesehen davon, dass es bei Dir auch schmutziges OO zu geben scheint, unterscheidest Du wenigstens zwischen OO-Sprache - sie es nicht gibt - und OO-unterstützende Sprachen. Wir sind uns diesbezüglich also einig.

    Shade Of Mine schrieb:

    Der Spaß heißt Reflection. Falsche Baustelle.

    Nein, ein sehr relevanter Punkt: wie dynamisch muss Polymorphie sein damit sie polymorphie ist?

    Ich sehe hier keine Relevanz. Begründe, warum Du sie siehst.
    Für OO muss ich zur Laufzeit auf überschriebene Funktionen zugreifen können, die objekt orientiert ausgewählt werden. Ich muss die Funktionen aber nicht zur Laufzeit austauschen können. Das ist die Baustelle von Reflection.

    Shade Of Mine schrieb:

    Bei wikipedia wird zB überladung bereits zur polymorphie gezählt. ist es nicht interessant dass deine definition nicht die einzig mögliche ist?

    Überladung gehört zur Polymorphie. Das entspricht meiner Definition.
    Überladung ist ein Part der Polymorphie, der nicht für OOP notwendig ist.
    Das Überschreiben hingegen ist notwendig. Das könnte ein Grund sein, warum man zwischen Überschreiben und Überladen unterscheidet?

    Shade Of Mine schrieb:

    zumal du ausser C++ und Java nichts kennst

    *smile*
    Das lohnt einen Kommentar einfach nicht.

    Shade Of Mine schrieb:

    Ich kann dir wirklich nur ans herz legen deinen horizont zu erweitern. Sprachen wie Self und LISP lernen dir ein komplett neues verständnis von OOP. Deshalb verstehst du uns hier auch nicht. Wir sind von dem Klassen denken komplett weg. Und ohne Klassen keine Vererbung und keine virtuellen Funktionen.

    Vererbung und virtuelle Funktion geht problemlos ohne Klassen, aber nicht ohne Klassifizierung.
    C hat keine Klassen und man kann trotzdem OOP verwenden.

    Damit Klassifizierung einfacher zu beschreiben ist, hat man in C++ Klassen.

    Lies meine Postings, alles schon längst beschrieben.



  • Xin schrieb:

    Exakt. Weil es eine Denkweise und keine technik ist.

    weil...

    Ich lese immer nur Behauptungen und "Du hast nicht recht".

    Hä?

    "Das ist ein Apfel" -- "Weil?" Was soll man denn dadrauf antworten? Es ist nicht logisch, dass ein Apfel "Apfel" heißt... es ist einfach so.



  • Xin schrieb:

    Entweder ist es "OO" oder nicht "OO".

    klingt sehr vereinfacht. warum muss alles schwarz oder weiß sein? kann nicht etwas grau sein?

    in c++ habe ich zB programme die teilweise aus reinem C code bestehen - weil es eben alter Code ist, der nach und nach an C++ angepasst wird. Ist jetzt alles OO oder sind nur teile OO oder ist garnichts OO?

    Abgesehen davon, dass es bei Dir auch schmutziges OO zu geben scheint, unterscheidest Du wenigstens zwischen OO-Sprache - sie es nicht gibt - und OO-unterstützende Sprachen. Wir sind uns diesbezüglich also einig.

    Was ist schmutziges OOP?
    Ich betone doch die ganze Zeit, dass OO deine Denkweise ist. Also gibt es in meinen Augen auch keine OO Sprachen.

    Wenn du JS programmiert hast - dann erklär mir mal fix wieso du dort keine OO hast. Oder hast du sie doch - wenn ja, dann widersprichst du dir ja, weil es in JS keine virtuellen Funktionen gibt. Es gibt kein dynamisches dispatchen.

    Ich sehe hier keine Relevanz. Begründe, warum Du sie siehst.
    Für OO muss ich zur Laufzeit auf überschriebene Funktionen zugreifen können, die objekt orientiert ausgewählt werden. Ich muss die Funktionen aber nicht zur Laufzeit austauschen können. Das ist die Baustelle von Reflection.

    Warum?
    Ich rede nicht von austauschen zur Laufzeit. Ich rede einfach nur von Laden von Klassen zur Laufzeit. Warum ist es Polymorphie wenn ich die Klassen die es gibt doch eh statisch vor mir habe? Wo trennst du ab wann etwas zu statisch für Polymorphie wird.

    Nehmen wir das Shape-Circle-Triangle Beispiel. So wirklich toll dynamisch ist es nicht, weil ich ja nur Circle und Triangle habe. Warum ist es dennoch Polymorphie? Schließlich stehen die Klassen zur Compiletime fest die es gibt. Wirklich dynamisch wäre es erst, wenn man zur Laufzeit unendliche neue Klassen nachladen würde.

    Worauf ich hinaus will ist: du ziehst einen Trennstrich den es nicht mehr gibt. Moderne VMs wie Java und .NET erlauben es die Compiletime der Runtime gleichzusetzen. Es gibt keine "das ist statisch" und "das ist dynamisch" Situationen mehr. Denn die Kompilierung findet während der Laufzeit statt und ich kann jederzeit neue Elemente nachladen.

    Shade Of Mine schrieb:

    Überladung gehört zur Polymorphie. Das entspricht meiner Definition.
    Überladung ist ein Part der Polymorphie, der nicht für OOP notwendig ist.
    Das Überschreiben hingegen ist notwendig. Das könnte ein Grund sein, warum man zwischen Überschreiben und Überladen unterscheidet?

    Nach welchen Gesichtspunkten trennst du Polymorphie? Einfach wie du lustig bist...? Du sagst wunderschön dieser Teil ist OO, dieser Teil nicht - aber erklär echt mal wie du JS siehst: es gibt keine Vererbung, keine Polymorphie - es gibt dort nur Objekte.

    Vererbung und virtuelle Funktion geht problemlos ohne Klassen, aber nicht ohne Klassifizierung.
    C hat keine Klassen und man kann trotzdem OOP verwenden.

    Vererbung ist für dich also auch Object Cloning?



  • otze schrieb:

    Ich versuch mal eine weniger schwammige definition aufzustellen(ich hab kein mathematisches Studium und bin kein Diplominformatiker, darum: kreuzigt mich nicht).

    Keine Sorge, der Versuch ist nicht strafbar. 😉

    Wenn Du OOP definierst, warum definierst Du dann, was ein Objekt ist und was man damit machen darf und was nicht?

    Wir sind uns einig, dass ein Objekt "irgendein Ding" ist. Belassen wir es doch dabei, wo liegt der Vorteil sich einzuschränken?
    Damit der Computer Objekte unterscheiden kann, benötigt ein Objekt eine Typinformation, darum leitet sich in Java alles von Object ab und für RTTI benötigt man in C++ ein Objekt, dass mindestens einen virtuellen Destruktor enthält. Objekte ohne virtuellen Destruktor haben diese Information nicht, können aber trotzdem "irgendein Ding" beschreiben, sind also Objekte.

    Um sich am Objekt orientieren zu können, benötigt man etwas, woran man sich orientieren kann. Das kann die VTable sein, die erstellt wird, sobald man die erste virtuelle Funktion erstellt.
    Man kann Objekte aber auch unterscheiden, in dem man jedem Objekttyp eine ID verpasst und danach entscheidet. Das ist sehr unschön, aber darüber lässt sich OOP realisieren.
    Man kann auch jedem Objekt Funktionspointer mitgeben, die - abhängig vom Objekt - angeben, wo man hinspringt. Die müssen objekttypabhängig initialisiert werden und obwohl sie vom (statischen) Typ abhängig sind, finden sie sich nicht in einer statischen Jumptable, sondern im Objekt.

    Für Multimethoden gilt das gleiche: Der Objekttyp muss im Objekt bekannt sein. Statt über Jumptable zu gehen, untersucht man die ObjektTypen und entscheidet sich dann für die passende Funktion.

    In allen Fällen wird abhängig vom Objekttyp gehandelt. Das alles ist OOP. Und das ist auch die Definition von OOP:
    "OOP liegt vor, wenn Objekte sich abhängig von ihrem Objekttyp verhalten und nicht abhängig vom ReferenzTyp, der auf das Objekt zeigt.":

    #include <iostream>
    
    class Tier 
    { 
      public: 
        void GibLaut() { std::cout << "Hallo!"; }   // mit virtual wäre es OOP.
    }; 
    
    class Katze : public Tier 
    { 
      public: 
        void GibLaut() { std::cout << "Miau"; } 
    };
    
    int main( void )
    {
      class Tier * tier  = new Katze(); 
      tier->GibLaut();  
    }
    

    Jester schrieb:

    Xin schrieb:

    Exakt. Weil es eine Denkweise und keine technik ist.

    weil...

    Ich lese immer nur Behauptungen und "Du hast nicht recht".

    Hä?

    "Das ist ein Apfel" -- "Weil?" Was soll man denn dadrauf antworten? Es ist nicht logisch, dass ein Apfel "Apfel" heißt... es ist einfach so.

    OOP ist eine Technik. Ich habe ausführlich erklärt warum. Grade eben wieder. Es geht also doch.



  • Xin schrieb:

    In allen Fällen wird abhängig vom Objekttyp gehandelt. Das alles ist OOP. Und das ist auch die Definition von OOP:
    "OOP liegt vor, wenn Objekte sich abhängig von ihrem Objekttyp verhalten und nicht abhängig vom ReferenzTyp, der auf das Objekt zeigt.":

    Und warum genau ist dann die Definition
    "Objekt orientierung bedeutet sich an den Objekten zu orientieren [was das verhalten des Programmes betrifft]" falsch?

    Du wandelst dich langsam doch noch in die richtige Richtung - auch wenn dasn eine 180° Kurve ist.

    Nichts anderes als das sagen wir hier die ganze Zeit: OOP ist eine Denkweise in der das Objekt das Zentrum dastellt. Ich brauche dafür aber keine dynamische Polymorphie - ich kann das auch mit statischer machen - solange das Objekt das Zentrum ist, das Objekt das verhalten festlegt.

    PS:
    deine Definition impliziert dass es Typen und Referenzen gibt - 2 Sachen die ich nicht unbedingt voraussetzen würde um ein OO Programm zu haben.



  • Xin schrieb:

    "OOP liegt vor, wenn Objekte sich abhängig von ihrem Objekttyp verhalten und nicht abhängig vom ReferenzTyp, der auf das Objekt zeigt.":

    Das ist aber unlogisch. Ein Objekt muss sich immer so verhalten, wie der Referenztyp der auf es zeigt, denn der Referenztyp gibt die definition darüber, was das Objekt ist. Du kannst das Objekt nicht anders verwenden als der Referenztyp zulässt, und der Objekttyp darf sich niemals anders verhalten als das was die zusicherungen erlauben.

    Im Zuge dieser Definition ist es völlig egal, ob sich nun der Referenztyp selbst um das verhalten kümmert, oder ob in anderes Objekt diese Arbeit erledigt, es gilt immer "pacta sunt servanda"- verträge müssen eingehalten werden. Solange dies gilt ist es für den aufrufer nebensächlich, was passiert, er fordert einen vertrag ein, und das Objekt kümmert sich darum, das er eingehalten wird.

    Am Ende ist OOP nicht mehr als das. Ich halte mich an bestehende Verträge mit den Objekten und tue das, was mir erlaubt wird, aber erstelle meinerseits neue Verträge, an die sich andere Objekte halten müssen.



  • Dieser Thread hat Kult-Potenzial. 👍



  • Shade Of Mine schrieb:

    Xin schrieb:

    In allen Fällen wird abhängig vom Objekttyp gehandelt. Das alles ist OOP. Und das ist auch die Definition von OOP:
    "OOP liegt vor, wenn Objekte sich abhängig von ihrem Objekttyp verhalten und nicht abhängig vom ReferenzTyp, der auf das Objekt zeigt.":

    Und warum genau ist dann die Definition
    "Objekt orientierung bedeutet sich an den Objekten zu orientieren [was das verhalten des Programmes betrifft]" falsch?

    Es geht um die Algorithmen, die abhängig vom Objekttyp zur Laufzeit unterschiedliche Funktionen aufrufen.
    Ich weiß jetzt nicht, in welchem Zusammenhang Du den Satz grade zitierst oder schreibst. Solange sich nur Programmierer an Objekten orientieren, nicht aber die Algorithmen, ist er falsch.
    Wenn Du statt "Objekten" "Objekttypen" meinst, wäre ich für die Ablehnung von Referenztypen dankbar, denn dann wären solche Threads überflüssig.

    Shade Of Mine schrieb:

    Nichts anderes als das sagen wir hier die ganze Zeit: OOP ist eine Denkweise in der das Objekt das Zentrum dastellt. Ich brauche dafür aber keine dynamische Polymorphie - ich kann das auch mit statischer machen - solange das Objekt das Zentrum ist, das Objekt das verhalten festlegt.

    Du brauchst keine dynamische Polymorphie, das habe ich nie behauptet.
    Ich sagte, dass "virtual" dynamische Polymorphie benötigt.
    Und dynamische Polymorphie braucht zwangsläufig Vererbung.
    Vererbung geht nur mit Klassifizierung, in C durch Klassen.
    Schlussfolgerung: für OOP-Unterstützung von C++ benötigst Du Klassifizierung, Vererbung, dynamische Polymorphie (also virtual).

    Und ich sagte mehrfach, dass virtual nicht für OOP benötigt wird. Verzichtest Du auf virtual, wirst Du von C++ auch nicht unterstützt und musst Du Deine Objektorientierung selbst implementieren. Also statische Jumptables aufwendig nachprogrammieren oder die in C häufig (fehleranfällige) verwendete Möglichkeit nehmen:

    void oop_function( char * object )
    {
      if     ( object[0] == 1 ) printf( "%s\n", &object[1] );
      else if( object[0] == 2 ) printf( "%c\n",  object[1] );
      else if( object[0] == 3 ) printf( "%d\n",  object[1] );
      ...
    }
    

    Das ist schwer zu warten, sieht scheiße aus und ist langsam. Es ist aber trotzdem OOP, weil abhängig vom Objekt (das auch keine "class" sein muss) unterschiedliche Funktionen gerufen werden.
    Das ist etwa das Level von Multifunktionen, lediglich ist ausformuliert, was ein Compiler übersetzen würde.
    Und es ist verdammt gut, dass diese ausgeschriebene Form von OOP heutzutage verpöhnt ist - es ändert aber nichts daran, dass es eine Form von objektorientierte Programmierung ist.

    In C++ würde ich die Objekte klassifizieren und die Sache über virtual functions regeln, weil C++ OOP unterstützt, damit lässt es sich besser warten, sieht es nicht mehr scheiße aus und wird schneller. (alles schon geschrieben...)

    Das x-Mal gepostete Tier => Katze Beispiel, ist ohne virtual nicht OOP, weil egal ist, mit welchem Objekt Tier::GibLaut() gerufen wird, es kommt Hallo raus.



  • otze schrieb:

    Xin schrieb:

    "OOP liegt vor, wenn Objekte sich abhängig von ihrem Objekttyp verhalten und nicht abhängig vom ReferenzTyp, der auf das Objekt zeigt.":

    Das ist aber unlogisch. Ein Objekt muss sich immer so verhalten, wie der Referenztyp der auf es zeigt, denn der Referenztyp gibt die definition darüber, was das Objekt ist.

    Falsch.
    Ein Referenztyp gibt an, was das Objekt ist oder, zu welcher Oberklasse er zugeordnet wird.

    BITTE schau Dir das Tier <-> Katze Beispiel an, kompilier es.

    Das Objekt ist eine Katze, aber handelt nicht wie eine Katze. Es ist nicht Objektorientiert, weil nach dem Referenztyp (Tier) entschieden wird Tier::GibLaut() aufzurufen, statt Katze::GibLaut().

    otze schrieb:

    Du kannst das Objekt nicht anders verwenden als der Referenztyp zulässt, und der Objekttyp darf sich niemals anders verhalten als das was die zusicherungen erlauben.

    Doch kannst Du, denn genau das ist, was Objektorientierung ausmacht.



  • Xin schrieb:

    Doch kannst Du, denn genau das ist, was Objektorientierung ausmacht.

    Also wirklich, billiger geht es nicht: Gerade klärst Du ihn erst darüber auf, was ein Referenztyp wirklich ist, und jetzt trittst Du hier noch nach. 🙄

    Xin schrieb:

    Das x-Mal gepostete Tier => Katze Beispiel, ist ohne virtual nicht OOP, weil egal ist, mit welchem Objekt Tier::GibLaut() gerufen wird, es kommt Hallo raus.

    Im Bereich der minimalen Voraussetzungen "meiner" Definition kommt man aber gar nicht in die Verlegenheit, Klassen abzuleiten.

    Natürlich ist Dein Beispiel eins objektorientierter Programmierung- aber nicht wegen der Verwendung von virtual, sondern weil Du Dich entschlossen hast, statt wild verstreuter Daten und Funktionen eine Klasse zu programmieren (Verzeihung, "zu schreiben", eine Klasse ist ja kein Algorithmus) und sie dazu zu benutzen, ein Programm zu formulieren, das mit Objekten arbeitet, die die so definierten Eigenschaften haben. Ich sehe nicht, was daran nun schwammig ist (wer soll das übrigens behauptet haben?).

    Xin schrieb:

    Es ist aber trotzdem OOP, weil abhängig vom Objekt (das auch keine "class" sein muss) unterschiedliche Funktionen gerufen werden.

    Ich merke mir als intellektuelle Höhepunkte von und für heute:
    1. Klassen müssen keine Objekte sein (logisch, den U-Boote tanzen nicht)
    2. Der folgende Codeschnipsel ist OOP, weil abhängig vom Objekt verschiedene Funktionen gerufen werden:

    class Katze
    {
      public:
        void GibLaut() { std::cout << "Miau"; }
    };
    
    class Hund
    {
      public:
        void GibLaut() { std::cout << "Wau"; }
    };
    
    Katze k;
    Hund h;
    
    h.GibLaut();
    k.Giblaut();
    

    Zu einer anderen Frage von Dir: Als geübter Definierer sollte schon klar sein, daß Einzelteile einer Definition ggf. auch definiert sein müssen. Wenn Du OOP definierst, mußt Du also automatisch auch O, O und P definieren. Und im Prinzip können wir jetzt schon aufhören, weil Du die Definition von O dazu genutzt hast, "meine" Definition für viel zu allgemein zu erklären. "mutwillig falsche Interpretation".



  • Xin schrieb:

    Es geht um die Algorithmen, die abhängig vom Objekttyp zur Laufzeit unterschiedliche Funktionen aufrufen.
    Ich weiß jetzt nicht, in welchem Zusammenhang Du den Satz grade zitierst oder schreibst. Solange sich nur Programmierer an Objekten orientieren, nicht aber die Algorithmen, ist er falsch.

    Dass man da so einfach trennen kann... Schliesslich schreibt der Programmierer ja den Algorithmus und ich kann mir schwer vorstellen dass der Programmierer das Verhalten vom Objekt vorgeben lässt dies aber nicht in den Algorithmus einbaut. Irgendwie widerspricht sich da etwas.

    Wenn Du statt "Objekten" "Objekttypen" meinst, wäre ich für die Ablehnung von Referenztypen dankbar, denn dann wären solche Threads überflüssig.

    Typen sind ein Konzept dass einige Sprachen nicht wirklich haben.

    Du brauchst keine dynamische Polymorphie, das habe ich nie behauptet.
    Ich sagte, dass "virtual" dynamische Polymorphie benötigt.
    Und dynamische Polymorphie braucht zwangsläufig Vererbung.
    Vererbung geht nur mit Klassifizierung, in C durch Klassen.
    Schlussfolgerung: für OOP-Unterstützung von C++ benötigst Du Klassifizierung, Vererbung, dynamische Polymorphie (also virtual).

    Aber das alles ist komplett uninteressant. Wir alle wissen welche Features C++ bietet. Die Frage ist: definieren diese Feature OOP. Lass C++ und Java einfach mal ruhen. Nur weil virtual in C++ sinnvoll ist um gute dynamische Polymorphie zu erreichen bedeutet dass nicht, dass virtual OOP definiert. Und es geht hier um OOP und nicht um C++.

    Ich behaupte weiterhin: diese Features sind Ausdrucksformen - ein paar von vielen Möglichen.

    Und ich sagte mehrfach, dass virtual nicht für OOP benötigt wird.

    Du sagst aber dynamische Polymorphie ist nötig für OOP und statische Polymorphie ist kein Teil der OOP. Genau das hinterfrage ich hier.

    Das x-Mal gepostete Tier => Katze Beispiel, ist ohne virtual nicht OOP, weil egal ist, mit welchem Objekt Tier::GibLaut() gerufen wird, es kommt Hallo raus.

    Und genau das ist nicht wahr:

    class Hund {
    public:
      void gib_laut() { cout<<"wau wau"; }
    };
    
    class Katze {
    public:
      void gib_laut() { cout<<"miau"; }
    };
    
    template<typename Tier>
    void foo(Tier* t) {
      t->gib_laut();
    }
    

    voila - das Objekt bestimmt das Verhalten.

    Die Frage ist: warum lässt du das nicht als OOP gelten? Vermutlich weil es statisch ist und schon zur Compiletime feststeht. Nun, was wenn ich einen C++ Interpreter hernehme - dann steht alles erst zur Laufzeit fest.



  • Xin schrieb:

    Falsch.
    Ein Referenztyp gibt an, was das Objekt ist oder, zu welcher Oberklasse er zugeordnet wird.

    BITTE schau Dir das Tier <-> Katze Beispiel an, kompilier es.

    das ohne virtual? ich kenne das ergebnis. und nun? Das ist auch das, was mir das interface zusichert. Nichts magisches, nichts ungewöhnliches. Es gibt einen laut zurück, und den habe ich verlangt. Das Objekt hat das Interface eingehalten. Und gleichzeitig auch nicht, aufgrund des logischen Fehlers. Das passiert aber oft, nennt man Bug. damit mein ich nicht, dass kein "Miau" ausgegeben wird, sondern "Hallo". Als Mensch erwarte ich nicht unbedingt, dass ein tier reden kann, ausser natürlich ich bin der Meinung, dass der Mensch biologisch ein Tier ist, für sicher 60% der menschen ist das aber höchst befremdlich.

    Das Objekt ist eine Katze, aber handelt nicht wie eine Katze. Es ist nicht Objektorientiert, weil nach dem Referenztyp (Tier) entschieden wird Tier::GibLaut() aufzurufen, statt Katze::GibLaut().

    Das ist aber nur logisch falsch, denn der Referenztyp kann diese Aufgabe ebenso erfüllen.

    class Tier
    {
        private: 
            string laut;
        public:
            Tier():laut("Hallo"){}
            Tier(const string& laut):laut(laut){}
    
            void gibLaut(){std::cout<<laut<<"\n";}
    };
    class Katze: public Tier
    {
        public:
            Katze():Tier("Miau"){}
    };
    
    int main()
    {
      Tier* tier  = new Katze();
      tier->GibLaut();  
    }
    

    Das Ergebnis gibt das was wir erwarten. Das objekt verhält sich dem Vertrag entsprechend und gibt uns den geforderten laut zurück. logisch und semantisch korrekt 👍
    Ist das nun OOP?

    mal davon ab: wenn wir das Objekt nicht selbst erstellen würden, könnten wir sogar(nach der philosophischen diskussion ob der Mensch auch ein Tier ist) zum Schluss kommen, dass "Hallo" durchaus korrekt ist, was meine Meinung verstärkt, dass der Vertrag das wichtige an der OOP ist, kein virtual.



  • Vielleicht erstmal Begrifsklärung Polymorphie:

    Beispiel Coercion-Polymorphie:

    void foo (double x)
    {}
    
    double bar = 0.0;
    foo (bar);
    
    int baz = 0;
    foo (baz);
    

    foo lässt sich mit Objekten verschiedenen Typs aufrufen.

    Überladungs-Polymorphie:

    void foo (double x)
    {}
    void foo (int x)
    {}
    
    double bar = 0.0;
    foo (bar);
    
    int baz = 0;
    foo (baz);
    

    foo lässt sich mit Objekten verschiedenen Typs aufrufen.

    Parametrische Polymorphie:

    template<typename T>
    void foo (T x)
    {}
    
    double bar = 0.0;
    foo (bar);
    
    int baz = 0;
    foo (baz);
    

    foo lässt sich mit Objekten verschiedenen Typs aufrufen.

    ...

    Einzig bei der Inklusions-Polymorphie wird dann dynamisch entschieden.

    struct X {
       virtual void foo() {}
    };
    struct Y : X {
       virtual void foo() {}
    };
    
    X x;
    Y y;
    
    X * bar = x;
    
    bar->foo();  // ist jetzt leider die C++-Syntax. Cooler wäre eine Sprache, die die Syntax foo(bar) verwenden würde
    
    bar = y;
    
    bar->foo();
    

Anmelden zum Antworten