Performancemythen?



  • Xin schrieb:

    finix schrieb:

    Wo ist sie denn, deine "scharfe gezogene Definition" von OOP?

    Du kannst sie auf den letzten ähh... 20-30 Seiten lesen.
    Die 40 packen wir wohl noch ^^

    Ich lege die Tage eine Zusammenfassung vor, die ich dann zur Diskussion stelle.

    Äh, ja, das hört sich tatsächlich nach scharf gezogener Definition an. Ist denn nicht eine deiner Quellen online verfügbar, so dass du bis dahin auf diese verweisen könntest? 😃



  • finix schrieb:

    Xin schrieb:

    finix schrieb:

    Wo ist sie denn, deine "scharfe gezogene Definition" von OOP?

    Du kannst sie auf den letzten ähh... 20-30 Seiten lesen.
    Die 40 packen wir wohl noch ^^

    Ich lege die Tage eine Zusammenfassung vor, die ich dann zur Diskussion stelle.

    Äh, ja, das hört sich tatsächlich nach scharf gezogener Definition an. Ist denn nicht eine deiner Quellen online verfügbar, so dass du bis dahin auf diese verweisen könntest? 😃

    Jemand warf folgenden Link rein: Stroustrup: What is OOP?.
    Der Link steht von meiner Seite nicht mehr zur Diskussion, wenn Du etwas dazu anmerken möchtest, blättere zurück, Du wärst vermutlich nicht der erste, der etwas dazu anmerkt.

    Ich zitierte schon ein paar Sachen und ansonsten sagte ich auch schon, dass eine Zitatschlacht weder für die eine oder andere Seite ein Beweis darstellt.
    Es zählt schließlich nicht, wieviele etwas sagen, sondern wie gut sie es begründen können.

    Lass es mich anders formulieren: Das eigene Hirn zu nutzen bringt mehr, als Texte zu zitieren, ohne zu wissen, ob die jeweiligen Autoren ihr Hirn benutzt haben oder nur von jemand anderem abgeschrieben haben.



  • [quote="Xin"]
    Wo ist da ein abstraktes Konzept, dass nicht im Sourcecode vorkommt?

    Ich pack den Code hier nochmal rein, damit wir überhaupt sicher sind, dass wir vom gleichen sprechen:

    Xin schrieb:

    Shade Of Mine schrieb:

    Mir ist gerade langweilig, deshalb ein kleines Gedankenspielchen:

    class Triangle {
    public:
      void draw();
    };
    
    class Circle {
    public:
      void draw();
    };
    
    template<typename Shape>
    void foo(Shape* s) {
      s->draw();
    }
    

    Das Konzept hier ist Shape. Genau wie in Java oder sonstwo wo man eine abstrakte Klasse/Interface hätte. Lediglich manifestiert es sich nicht direkt im Code in form einer Klasse/Interface sondern viel mehr im Sinne eines abstrakten Konzepts.



  • Shade Of Mine schrieb:

    Xin schrieb:

    Wo ist da ein abstraktes Konzept, dass nicht im Sourcecode vorkommt?

    Ich pack den Code hier nochmal rein, damit wir überhaupt sicher sind, dass wir vom gleichen sprechen:

    Shade Of Mine schrieb:

    Mir ist gerade langweilig, deshalb ein kleines Gedankenspielchen:

    class Triangle {
    public:
      void draw();
    };
    
    class Circle {
    public:
      void draw();
    };
    
    template<typename Shape>
    void foo(Shape* s) {
      s->draw();
    }
    

    Das Konzept hier ist Shape. Genau wie in Java oder sonstwo wo man eine abstrakte Klasse/Interface hätte. Lediglich manifestiert es sich nicht direkt im Code in form einer Klasse/Interface sondern viel mehr im Sinne eines abstrakten Konzepts.

    Ich sehe da nichts abstraktes?! Das alles statisch.
    Oder glaubst Du, dass ein Algorithmus dynamisch wird, weil Teile des Programms über ein Template erzeugt wurde?

    Wenn Du in C++ etwas abstraktes formulieren willst, dann musst Du sowas formulieren:

    class Figure
    {
      public:
        virtual void draw() = 0;  // pure virtual == abstract
    }
    
    class Triangle : public Figure {
    public:
      void draw();
    };
    
    class Circle : public Figure {
    public:
      void draw();
    };
    
    template<typename Shape>
    void foo(Shape* s) {
      s->draw();
    }
    

    Und damit ist es jetzt auch OOP.

    Entweder verstehe ich nicht, was Du unter "Abstrakt" verstehst oder Du kommst in C++ um virtual nicht herum.



  • Xin schrieb:

    Wenn a.foo() OOP ist, ohne virtuell zu sein, dann ist printf() ebenfalls OOP.

    a.foo() ist OOP, weil die Funktionalität "foo" mit Daten zum Objekt "a" zusammengeführt sind. Bei printf gibt es keine Zusammenführung mit irgendwas.

    Ich sehe da nichts abstraktes?! Das alles statisch.
    Oder glaubst Du, dass ein Algorithmus dynamisch wird, weil Teile des Programms über ein Template erzeugt wurde?

    Lerne generische Programmierung.



  • Xin schrieb:

    rüdiger schrieb:

    Xin schrieb:

    dv_ schrieb:

    Du glaubst allen ernstens, dass OOP nur aus dynamic dispatch besteht? Mann, du hast wirklich eiskalt alle Messlatten vergraben. Lass dir gesagt sein: OOP ist mehr als nur dynamic dispatch.

    Ist das alles, was als Begründung kommt?
    Wenn Du mir etwas mitteilen möchte, dann stelle nicht nur Behauptungen auf, sondern begründe sie.

    a.foo();
    

    Nachricht an ein Objekt gesendet => OOP.

    Sorry, hier ist es leider schon vorbei.
    Das ist Syntax, die Realität sieht auch bei a.foo(); so aus:

    ClassOfA::foo( a );
    

    Aufruf einer statischen Funktion, mit dem Objekt als erstem Argument.

    Wenn a.foo() OOP ist, ohne virtuell zu sein, dann ist printf() ebenfalls OOP.

    foo ist eine Nachricht an a. Was der Compiler daraus macht ist egal. Ganz zu schweigen davon, dass du das nicht beurteilen kannst, da du ja nicht weißt was a ist. Vielleicht ist es ja sogar eine Nachricht die nicht akzeptiert wird, was man wegen dem statischen OOP bei C++ ja zur Compilezeit erfährt. Was aber nicht bei jeder Sprache so seien muss! (Tellerrand Problematik)

    Meinetwegen kann der Compiler aus der Nachricht die ich an das Objekt Schicke auch Senf mit Soße oder Speiseeis oder ne Birne machen. Hauptsache das Ergebnis stimmt.

    (ob es nun ein call 0xAFFE oder ein call %eax ist, interessiert mich nicht (Ausnahme ist natürlich µOptimierung))

    Was hat printf damit zu tun? Wo siehst du da Nachricht und Objekt?



  • Xin schrieb:

    Ich sehe da nichts abstraktes?! Das alles statisch.
    Oder glaubst Du, dass ein Algorithmus dynamisch wird, weil Teile des Programms über ein Template erzeugt wurde?

    Abstrakt und Statisch sind keine Gegensätze und was genau meinst du mit dynamisch?



  • Xin schrieb:

    Tim schrieb:

    Was haben wir hier eigentlich. Wir haben zwei Parteien: Die eine hat eine schwammige, unpräzise Definition von OOP, die andere eine harte, präzise. Was mich dabei aber wundert ist, dass in einem Forum mit den übelsten Pedanten, ANSI-Standard-Fetischisten und undefined-behaviour-Propheten eben die unexakte, schwammige Definition besser angenommen wird.

    👍

    In dem Fall bin ich wohl der Pedant ^^
    Das ist okay, denn es stimmt hier ja. Ich möchte nur nebenher erwähnen, dass zwar scharfe gezogene Definitionen schätze, aber deswegen nicht grundsätzlich pedantisch bin.
    Hier bin ich Pedant, solange niemand die Frage auf Seite 11 sinnvoll beantwortet oder es wenigstens versucht. 😎

    Es gibt zahlreiche andere Definitionen hier in dem Thread, die ebenfalls "scharf" sind. Deine ist einfach nur Falsch in der Hinsicht, dass die Mehrheit der Programmierer sie wohl einfach nicht teilt. Aber wie ich schon sagte: Du kannst meinetwegen auch Blau zu Grün sagen...



  • rüdiger schrieb:

    Komisch finde ich nur, dass der Graham Artikel hier vieles voraus gesehen hat...

    Der ist nicht von Graham! 😡

    Der ist von Rees! 💡

    (Wir reden schon von http://www.paulgraham.com/reesoo.html, oder?)



  • Xin schrieb:

    class Figure
    {
      public:
        virtual void draw() = 0;  // pure virtual == abstract
    }
    
    class Triangle : public Figure {
    public:
      void draw();
    };
    
    class Circle : public Figure {
    public:
      void draw();
    };
    
    template<typename Shape>
    void foo(Shape* s) {
      s->draw();
    }
    

    Und damit ist es jetzt auch OOP.

    Das ist oop? wieso sollte das denn nach deienr definition oop sein? Du argumentierst doch immer, dass der Compiler diese virtual komponente sehen muss.
    Du sagst sogar, dass der compiler, sobald der virtual overhead entfernt wird, aus dem oo code non oo code macht.

    Circle test;
    foo(&test);//kein virtueller funktionsaufruf
    

    so schießt du dir selbst ins knie(auch wenn du das oft genug getan hast)

    machst du hingegen sowas:

    Circle test;
    foo(static_cast<Figure*>(&test));
    //oder
    Figure* test2=new Circle;
    foo(test2);
    

    dann hast du templates nicht verstanden. Auch ein beinschuss.

    Entweder verstehe ich nicht, was Du unter "Abstrakt" verstehst oder Du kommst in C++ um virtual nicht herum.

    wikipedia:
    Im mathematischen Sinne bezeichnet Abstraktion einen Prozess, bei dem individuelle, zufällige Einzelheiten weggelassen (abstrahiert) werden, zugunsten des Allgemeinen, Wesentlichen.

    Es geht bei der Abstraktion nicht um "abstrakte methoden" oder "abstrakte Objekte", sondern zuallererst um den Denkvorgang. Was für Eigenschaften brauch ich? Was ist von ihnen für mein Problem wichtig?
    Daraus kristallisiert sich ein interface. Nun kannst du dich entscheiden es als abstrakte basisklasse zu implementieren, oder das interface als Denkonstrukt lassen, und mithilfe von templates einfach nur ein interface durch nutzung der methoden zu definieren.



  • rüdiger schrieb:

    Xin schrieb:

    rüdiger schrieb:

    Xin schrieb:

    dv_ schrieb:

    Du glaubst allen ernstens, dass OOP nur aus dynamic dispatch besteht? Mann, du hast wirklich eiskalt alle Messlatten vergraben. Lass dir gesagt sein: OOP ist mehr als nur dynamic dispatch.

    Ist das alles, was als Begründung kommt?
    Wenn Du mir etwas mitteilen möchte, dann stelle nicht nur Behauptungen auf, sondern begründe sie.

    a.foo();
    

    Nachricht an ein Objekt gesendet => OOP.

    Sorry, hier ist es leider schon vorbei.
    Das ist Syntax, die Realität sieht auch bei a.foo(); so aus:

    ClassOfA::foo( a );
    

    Aufruf einer statischen Funktion, mit dem Objekt als erstem Argument.

    Wenn a.foo() OOP ist, ohne virtuell zu sein, dann ist printf() ebenfalls OOP.

    foo ist eine Nachricht an a. Was der Compiler daraus macht ist egal.

    Wie da steht - ohne virtuell zu sein - kann da nicht objektorientiertes draus werden.

    rüdiger schrieb:

    Ganz zu schweigen davon, dass du das nicht beurteilen kannst, da du ja nicht weißt was a ist.

    Daher die Relativierung, dass die Aussage gilt, wenn virtual nicht gesetzt ist und zum anderen wurde direkt darunter die Klasse vorgestellt - ohne virtual. Daher kann ich das beurteilen.[/quote]

    rüdiger schrieb:

    Was hat printf damit zu tun? Wo siehst du da Nachricht und Objekt?

    Bitte lies das Posting exakt.

    printf ist eine statische Funktion. Sie ist nicht OOP.
    ClassOfA::foo( ClassOfA * ) ist eine statische Funtion. Sie ist nicht OOP.

    Wenn ClassOfA::foo( ClassOfA * ) OOP, wie behauptet wird, so ist printf ebenfalls OOP in Abhängigkeit des ersten Argumentes.

    Was der Compiler daraus mag Dir ja egal sein, aber es equivalent zum Sourcecode. Aus einem statischen Funktionsruf wird ohne Compilerfehler kein OOP mehr.

    rüdiger schrieb:

    Xin schrieb:

    Ich sehe da nichts abstraktes?! Das alles statisch.
    Oder glaubst Du, dass ein Algorithmus dynamisch wird, weil Teile des Programms über ein Template erzeugt wurde?

    Abstrakt und Statisch sind keine Gegensätze und was genau meinst du mit dynamisch?

    Wahl einer statischen Funktion aufgrund eines Algorithmus.
    Es gibt keine dynamischen Funktionen (ohne Reflection), es gibt virtuelle Funktionen, die aufgrund der OO-Technik eine statische Funktion aufrufen.

    rüdiger schrieb:

    Es gibt zahlreiche andere Definitionen hier in dem Thread, die ebenfalls "scharf" sind.

    Das wird in dem Thread nicht nur von mir bestritten.

    rüdiger schrieb:

    Deine ist einfach nur Falsch in der Hinsicht, dass die Mehrheit der Programmierer sie wohl einfach nicht teilt.

    Die Hinsicht, das die Mehrheit der Programmierer sie teilt, wäre somit richtig.
    Diese Mehrheit findet sich offenbar nicht in diesem Forum.



  • Xin schrieb:

    printf ist eine statische Funktion. Sie ist nicht OOP.
    ClassOfA::foo( ClassOfA * ) ist eine statische Funtion. Sie ist nicht OOP.

    Wenn ClassOfA::foo( ClassOfA * ) OOP, wie behauptet wird, so ist printf ebenfalls OOP in Abhängigkeit des ersten Argumentes.

    Was der Compiler daraus mag Dir ja egal sein, aber es equivalent zum Sourcecode. Aus einem statischen Funktionsruf wird ohne Compilerfehler kein OOP mehr.

    Und das ist von A bis Z falsch. Nochmal: ClassOfA::foo ist objektorientiert, WEIL CLASSOFA EINE ZUSAMMENFÜHRUNG VON DATEN UND FUNKTIONALITÄT IST. Und foo IST eine Funktionalität.

    Statisch = kein OOP, virtuell = OOP ist auf jeden fall komplett falsch.



  • otze schrieb:

    Xin schrieb:

    class Figure
    {
      public:
        virtual void draw() = 0;  // pure virtual == abstract
    }
    
    class Triangle : public Figure {
    public:
      void draw();
    };
    
    class Circle : public Figure {
    public:
      void draw();
    };
    
    template<typename Shape>
    void foo(Shape* s) {
      s->draw();
    }
    

    Und damit ist es jetzt auch OOP.

    Das ist oop? wieso sollte das denn nach deienr definition oop sein? Du argumentierst doch immer, dass der Compiler diese virtual komponente sehen muss.

    Hier ist doch alles offensichtlich. Für mich, wie auch für den Compiler.
    Zwischen Circle und Figure existiert die gerichtete, die Funktion draw wird objekt orientiert gesetzt.

    Das Template hat damit nix zu tun. Gibst Du als Typ "Figure" an, kannst Du problemlos und typsicher Circles und Triangles zeichnen. Du hättest auch direkt s->draw() schreiben können, das Template tut schließlich überhaupt nichts.

    rüdiger schrieb:

    Du sagst sogar, dass der compiler, sobald der virtual overhead entfernt wird, aus dem oo code non oo code macht.

    Ich sage, dass es eine (1) Möglichkeit gibt, wo der Compiler OOP entfernen kann. Die Möglichkeit ist genannt (es existiert keine Subklasse der Basisklasse mit virtueller Funktionalität) und die liegt hier nicht vor.
    Hier wird kein OOP entfernt.

    rüdiger schrieb:

    Circle test;
    foo(&test);//kein virtueller funktionsaufruf
    

    so schießt du dir selbst ins knie(auch wenn du das oft genug getan hast)

    Der Ruf der Templatefunktion foo ist rein statisch. Statischer Aufruf, kein OOP.
    Die Templatefunktion ruft die Funktion Shape::draw. Aufruf über OOP, wenn Shape::draw virtual definiert ist. Das ist z.B. der Fall, wenn Shape == Figure gesetzt wird. Ansonsten wird eine Template-Funktion foo erzeugt, die einen statischen Funktionsruf erzeugt. Dann kein OOP.

    Meinem Knie geht's wunderbar.

    rüdiger schrieb:

    machst du hingegen sowas:

    Circle test;
    foo(static_cast<Figure*>(&test));
    //oder
    Figure* test2=new Circle;
    foo(test2);
    

    dann hast du templates nicht verstanden. Auch ein beinschuss.

    Kompiliere es, teste es. Funktioniert doch alles, wie ich beschrieben hbae.

    Du kannst kein Objekt vom Typ Figure herstellen. Figure ist ein Interface, aber selbstverständlich darfst Du Figure::draw() aufrufen. Das ist kein statischer Aufruf, sondern genau das ist OOP.
    Abhängig vom Objekt (ob Circle oder Triangle) wird mit Hilfe von OOP die Funktion Circle::draw() oder Triangle::draw() aufgerufen.

    Wenn Beinschuss, dann nicht von mir. Ich arbeite sehr viel mit OOP und auch sehr viel mit Templates.
    Ich mache keine Schnellschüsse.



  • printf ist eine statische Funktion. Sie ist nicht OOP.
    ClassOfA::foo( ClassOfA * ) ist eine statische Funtion. Sie ist nicht OOP.

    Wenn ClassOfA::foo( ClassOfA * ) OOP, wie behauptet wird, so ist printf ebenfalls OOP in Abhängigkeit des ersten Argumentes.

    Nein, weil eben die bedeutung des sources eben nicht gleich der logischen bedeutung ist. printf ist wenn dann eine methode von stdout, aber dieser wird auch nur benutzt. printf ist keine funktion von string, weil es zwischen "Zeichenkette" und "standardausgabe" keine direkte logische verbindung gibt. Desweiteren hat das erste sprintf argument, der formatstring höchstens aggregationscharacter, er wird benutzt um die anderen argumente richtig formatieren zu können und das ergebnis wird auf stdout ausgegeben.

    Im gegensatz dazu steht foo in einer direkten logischen verbindung zu foo, denn als Mitglied von ClassOfA ist es auch auf jeden Fall teil der abstraktion.



  • otze schrieb:

    printf ist eine statische Funktion. Sie ist nicht OOP.
    ClassOfA::foo( ClassOfA * ) ist eine statische Funtion. Sie ist nicht OOP.

    Wenn ClassOfA::foo( ClassOfA * ) OOP, wie behauptet wird, so ist printf ebenfalls OOP in Abhängigkeit des ersten Argumentes.

    Nein, weil eben die bedeutung des sources eben nicht gleich der logischen bedeutung ist. printf ist wenn dann eine methode von stdout, aber dieser wird auch nur benutzt. printf ist keine funktion von string, weil es zwischen "Zeichenkette" und "standardausgabe" keine direkte logische verbindung gibt. Desweiteren hat das erste sprintf argument, der formatstring höchstens aggregationscharacter, er wird benutzt um die anderen argumente richtig formatieren zu können und das ergebnis wird auf stdout ausgegeben.

    Im gegensatz dazu steht foo in einer direkten logischen verbindung zu foo, denn als Mitglied von ClassOfA ist es auch auf jeden Fall teil der abstraktion.

    Die Verbindung bei printf zu (const char 😉 gibt es, aber sie ist natürlich an den Haaren herbei gezogen.
    Dennoch ist diese haarsträubende Verbindung genauso stark wie ClassOfA::foo( ClassOfA * this ): Es ist das erste Argument.

    Nochmals zur Verdeutlichung: "printf" ist nicht OOP. "ClassOfA::foo" ist in dem Beispiel genauso implementiert, wie "printf". In beiden Fällen wird der Aufruf nicht objektorientiert umgesetzt, sondern statisch.
    Eine objektorientierte Verbindung liegt dann vor, wenn von ClassOfA ein Interface für andere Klassen darstellt und die Funktion als virtuell oder abstrakt (virtual ...= 0;) gekennzeichnet wird.
    Dann wird erst abhängig vom Objekttyp die passende statische Funktion ausgesucht und anschließend aufgerufen: OOP.



  • Xin schrieb:

    Ich sehe da nichts abstraktes?! Das alles statisch.

    Abstrakt im Sinne wie Liebe ein abstraktes Nomen ist.
    Denk nicht immer in Java Bahnen. Es geht um OOP nicht um Java.

    Oder glaubst Du, dass ein Algorithmus dynamisch wird, weil Teile des Programms über ein Template erzeugt wurde?

    Ja. Denn Templates sind in dem Sinne dynamisch als dass sie nicht unänderbar sind. Ich kann sie dynamisch erweitern indem ich neue Objekte hinzufüge ohne den Ursprünglichen Code zu ändern. In einem C++ Interpreter kann ich das zur Laufzeit machen.

    Templates können zur Laufzeit erstellt werden - siehe C#. Wenn dort ein Generic auftaucht, dann schaut die VM erstmal nach ob eine neue Klasse erstellt werden soll. Und es spricht technisch nichts dagegen C++ Templates genauso zu implementieren. Damit hat man nichts statisches mehr.

    Es geht bei der OOP um das Denken. Wenn ich also das abstrakte Konzept - oder die Idee - von Shape einführe, sind beide Codes gleichwertig: C++ Templates und Java Interfaces. Ich kann mit keinem Code mehr machen als mit dem anderen - sie sind vollkommen gleichwertig.

    Ob ich nun ein Interface Shape einführe oder es nur im Geiste habe - ändert die Idee des Codes nicht und ändert faktisch sogar den ASM Code nicht - wenn der Compiler clever ist.



  • Xin, ich denke schon, dass wir Deine Definition inzwischen verstanden haben. Wir halten sie nur nach wie vor für falsch. Es bringt also nichts diese stoisch immer wieder zu wiederholen.

    Wenn ClassA::foo tatsächlich so wenig mit dem Objekt zu tun hat wie printf mit dem formatstring, dann hast Du recht. Es handelt sich dann um einen schlichten Designfehler, foo sollte dann nicht ClassA zugehörig sein. Normalerweise ist eine Funktion aber Member, weil sie Daten des Objektes verwendet, um gewisse Entscheidungen zu treffen und Operationen durchzuführen. Man könnte sagen (auch wenn ich das inzwischen für etwas ausgelutscht halte), das Programm orientiert sich am Objekt, nämlich dessen aktuellem Zustand. Und es wird ja keiner behaupten wollen, dass der Zustand eines Objektes in Wirklichkeit der Klasse zugehörig ist, oder?

    Du wirst dieser Definition zumindest den gleichen Grad an Präzision und Gültigkeit zugestehen müssen wie Deiner eigenen. Es steht schließlich nirgends geschrieben, dass "orientieren" heißt "orientiert sich am Typ". Das ist lediglich Deine persönliche Interpretation davon, die die meisten anderen offensichtlich nicht teilen.



  • Ich glaub ich versteh langsam wieso um Xins Definition so lange Diskussion gebildet hatt. Die Algemeine Definition von OOP ist
    "Wenn man Daten und Algorithmen zu Klassen abstrahiert und buendelt, von diesen Klassen einzelne Objekte erzeugt und diese Objekte nur noch ueber Nachrichten mit einander kommunizieren, dann ist es OOP."
    Xin stellt diese Definition in Frage, weil man nach dieser Definition alles als OOP bezeichnen kann. Man kann damit also dass

    interface Comparable; class Foo implements Comparable {}
    

    und

    printf(ausgabestream, eingabe)
    

    und

    class Foo { public: void nachricht(x); } foo.nachricht(x);
    

    und vieles andere als OOP bezeichnen.

    Also stellt Xin eine prezisere Definition auf:
    "Wenn man Daten und Algorithmen zu Klassen abstrahiert und buendelt, von diesen Klassen einzelne Objekte erzeugt und diese Objekte nur noch ueber Nachrichten mit einander kommunizieren, und es erst zur Laufzeit entschieden wird, welches einzelne Objekt diese Nachricht bekommt, dann ist es OOP."

    Also fuer euch ist OOP:
    - encapsulation,
    - inheritance,
    - or polymorphism
    Wobei das, mit genuegend Phantasie, sich auf alles anwenden laesst.

    Fuer Xin ist OOP:
    - encapsulation,
    - inheritance,
    - and polymorphism

    Wenn ClassA::foo tatsächlich so wenig mit dem Objekt zu tun hat wie printf mit dem formatstring, dann hast Du recht. Es handelt sich dann um einen schlichten Designfehler, foo sollte dann nicht ClassA zugehörig sein. Normalerweise ist eine Funktion aber Member, weil sie Daten des Objektes verwendet, um gewisse Entscheidungen zu treffen und Operationen durchzuführen. Man könnte sagen (auch wenn ich das inzwischen für etwas ausgelutscht halte), das Programm orientiert sich am Objekt, nämlich dessen aktuellem Zustand. Und es wird ja keiner behaupten wollen, dass der Zustand eines Objektes in Wirklichkeit der Klasse zugehörig ist, oder?

    Und wieder, kein einziges Wort ueber Polymorphismus. Wenn diese Daten also nicht im class-Space sind, sondern irgendwo anders gespeichert werden (z.B. in einer Datenbank), dann wird es nicht mehr OOP?



  • Shade Of Mine schrieb:

    Xin schrieb:

    Ich sehe da nichts abstraktes?! Das alles statisch.

    Abstrakt im Sinne wie Liebe ein abstraktes Nomen ist.
    Denk nicht immer in Java Bahnen. Es geht um OOP nicht um Java.

    Ich sehe da in keinerlei Hinsicht irgendwas abstraktes im Sinne von OOP in Deiner Definition.

    Shade Of Mine schrieb:

    Oder glaubst Du, dass ein Algorithmus dynamisch wird, weil Teile des Programms über ein Template erzeugt wurde?

    Ja. Denn Templates sind in dem Sinne dynamisch als dass sie nicht unänderbar sind. Ich kann sie dynamisch erweitern indem ich neue Objekte hinzufüge ohne den Ursprünglichen Code zu ändern. In einem C++ Interpreter kann ich das zur Laufzeit machen.

    Das ist dynamisch, aber nicht OOP. Neue Templates ändern nicht die Typen vorhandener Daten.

    Shade Of Mine schrieb:

    Templates können zur Laufzeit erstellt werden - siehe C#. Wenn dort ein Generic auftaucht, dann schaut die VM erstmal nach ob eine neue Klasse erstellt werden soll. Und es spricht technisch nichts dagegen C++ Templates genauso zu implementieren. Damit hat man nichts statisches mehr.

    Stimmt, ich kann das Programm zur Laufzeit umschreiben. Das ist dann nicht mehr statisch, aber wenn ich das Programm umschreibe und so nachträglich OOP einfüge oder zur Laufzeit entferne ist das Ändern des Programms nicht OOP, sondern Reflection.
    Selbstmodifizierender Code ist eine sehr alte Geschichte und gab's schon lange, bevor es mit Reflection standardisierte Interfaces dafür gab. Hier wird allerdings mit keinem Objekt gearbeitet, sondern der Code verändert.

    Shade Of Mine schrieb:

    Es geht bei der OOP um das Denken. Wenn ich also das abstrakte Konzept - oder die Idee - von Shape einführe, sind beide Codes gleichwertig: C++ Templates und Java Interfaces.
    Ich kann mit keinem Code mehr machen als mit dem anderen - sie sind vollkommen gleichwertig.

    Ähh... hier muss ich leider widersprechen.. Ein Java Interface entspricht einer Klasse ohne Daten und ausschließlich abstrakten Funktionen.

    class Interface
    {
      public:
        virtual void foo() = 0;
        virtual void bar() = 0;
    };
    

    Templates sind keine Interfaces, Templates sind eine Abstraktionsebene höher, so könntest Du mit z.B. Templates Interfaces erstellen.

    Templates sind keine Interfaces. Templates sind wieder eine ganz andere Baustelle.



  • DEvent schrieb:

    Ich glaub ich versteh langsam wieso um Xins Definition so lange Diskussion gebildet hatt. Die Algemeine Definition von OOP ist
    "Wenn man Daten und Algorithmen zu Klassen abstrahiert und buendelt, von diesen Klassen einzelne Objekte erzeugt und diese Objekte nur noch ueber Nachrichten mit einander kommunizieren, dann ist es OOP."
    Xin stellt diese Definition in Frage, weil man nach dieser Definition alles als OOP bezeichnen kann. Man kann damit also dass

    interface Comparable; class Foo implements Comparable {}
    

    und

    printf(ausgabestream, eingabe)
    

    und

    class Foo { public: void nachricht(x); } foo.nachricht(x);
    

    und vieles andere als OOP bezeichnen.

    Nein. printf hat keinerlei Kopplung zu irgendeinem Objekt. Einfach nur Funktionen in eine Klasse tun reicht nicht aus, damit es objektorientiert ist. Die Zusammenführung muss einen Sinn haben. Zusammenführung von Bitmapdaten mit draw_bitmap(), create_bitmap(), destroy_bitmap(), resize_bitmap() usw. ist sinnvoll.

    EDIT: OK, man könnte aus stdout ein Objekt machen und printf reinfügen....


Anmelden zum Antworten