Performancemythen?
-
Xin schrieb:
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.Wo ist sie denn, deine "scharfe gezogene Definition" von OOP?
Xin schrieb:
Hier bin ich Pedant, solange niemand die Frage auf Seite 11 sinnvoll beantwortet oder es wenigstens versucht.
Welche meinst du denn?
-
finix schrieb:
Xin schrieb:
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.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.
finix schrieb:
Xin schrieb:
Hier bin ich Pedant, solange niemand die Frage auf Seite 11 sinnvoll beantwortet oder es wenigstens versucht.
Welche meinst du denn?
Die Frage, die ich hustbaer stellte - sorry, war Seite 12:
xin schrieb:
hustbaer schrieb:
Wenn man diese Definition von OO(P) verwendet heisst das noch lange nicht dass man hier irgendwelche abstrakten Klassen, Polymorphie oder virtuelle Aufrufe braucht. Wenn ein Programm so entworfen ist dass "die Auswahl des auszuführenden Codes" immer zur Compile-Zeit erfolgen kann (ohne natürlich den "falschen" Code auszuwählen), dann ist das kein Grund warum das Programm nichtmehr "OO" wäre.
Und welche Begründung gibt es, es "OO" zu nennen?
Nachrichten gibt's in rein prozeduralen Sprachen, in C++ wird es in Funktionsaufrufen gehandhabt.
Man könnte auch überall, was da in Wirklichkeit ja auch steht, die Funktion korrekt ausschreiben:tier.Tier::Funktion( typ Parameter )
Das unterscheidet sich von
tier_Funktion( Tier * tier, typ Parameter )
nicht. Die Methode heißt Tier::Funktion( Tier *, typ ). Wo ist der Unterschied zu "tier_Funktion( Tier *, typ )?
Es passiert dasselbe und es wird auch dasselbe übersetzt. Es ist in der Implementierung identisch. Es ist semantisch identisch, beides kann als Nachricht übermittelt werden und beides wird in C++ als Funktionsaufruf umgesetzt.
Warum ist das eine für Dich "OO" und das andere nicht? Wo beschreibt die Masse einen Unterschied, der den Namen "objekt orientiert" rechtfertigt?...und beides wird in C++ als - statischer - Funktionsaufruf umgesetzt.
-
OK, ich habe ja lange tapfer durchgehalten, aber irgendwo auf seite 28 oder 29 bin ich ausgestiegen.
Ich weiß nicht, ob in den folgenden Seiten definiert wurde, was mit "reiner" OO gemeint ist, deswegen mache ich das noch eben und klinke mich dann volkommen aus.
Zunächst ein Bereich, in dem rein vs. unrein an der Tagesordnung steht: rein-funktionale Sprachen (Haskell, Clean, ...) vs. unreine (SML, O'Caml, ...). Rein Funktionale Sprachen kennen eben keinerlei imperative Konstrukte, wie Schleifen, etc. da sich der Zustand nicht ändern kann und Schleifen somit grundsätzlich entweder nie oder unendlich lang laufen würden.
Analog ist es mit der reinen Objektorientierung zu verstehen.
C++ verwendet z.B.if (x > y) ... else ...
Wohin rein-Objektorientierte Sprachen solche Konstrukte natürlich gar nicht kennen. Alles ist ein Objekt. Equivalent in Smalltalk:
(x > y) ifTrue: [...] ifFalse: [...].
Dem Objekt x wird die Nachricht > mit dem Argument y geschickt. Dieses Antwortet entweder mit einem Objekt des Typs "True" oder mit einem Objekt des Typs "False".
Beide implementieren die Methode "ifTrue:ifFalse": (Argumente werden hinter Doppelpunkte in den Funktionsnamen eingestreut). "True" implementiert sie so, dass sie dem ersten übergebenen Block die Nachricht "value" schickt und den zweiten ignoriert. "False" implementiert sie so, dass sie dem zweiten übergebenen Block die Nachricht "value" shickt und den ersten ignoriert. (Code-Blöcke sind natürlich auch Objekte, da alles ein Objekt ist und deswegen ist es kein Problem einen zu übergeben.)Rein objektorientiert bedeutet also nicht durch nicht-Objektorientierte Konstrukte "verunreinigt".
So. Das wars von mir zu dem Thema.
-
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.