Methoden mit bool-Parametern und "Lesbarkeit" im Kontext
-
CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Xin schrieb:
Nur für den Fall, dass Du es nicht gesehen hast: Die Sitze in einem Auto beschreiben wunderbar genau das, was ich als Member ("besteht-aus") beschreiben würde, denn ein Auto verhält sich nicht wie ein Sitz und ist auch kein Sitz.
Ein Auto verhält sich auch nicht wie eine Geschwindigkeit (kann die sich überhaupt verhalten?) - ein Auto hat eine Geschwindigkeit. (ja, die Beziehung Auto<->Geschwindigkeit ist etwas technisch anderes als Auto<->Sitz oder Auto<->Motor, aber sie liegt definitiv näher an "hat-ein" als an "ist-ein")
Hey, CStoll, das wird ja richtig philosophisch.
Okay, spielen wir mal mit.
Eine Geschwindigkeit ist etwas nichts Greifbares, also kann man Geschwindigkeit nicht besitzen, also auch nicht haben. Für Member verwendet man auch gerne die Beziehung "besteht aus" passt hier auch nicht, denn ein Auto besteht aus keinem Stück Geschwindigkeit.
Ein Auto ist mit einer Geschwindigkeit unterwegs.
Ein Auto ist schnell.Geschwindigkeit ist ein Zustand.
Ein Fenster ist ein Zustand. Und wenn man Dialog von Fenster ableitet, so erbt ein Objekt Dialog auch den Zustand Fenster.Ein Fenster ist kein Zustand, sondern ein (mehr oder weniger) real existierendes Objekt. Ein Dialog ist eine spezielle Art von Fenster.
Und ja, für Zustände gibt es in C++ kein eigenes Sprachmittel (du hast deine Typerweiterungen für sowas entwickelt(?)).
Alles ist ein Objekt? Da muss ich einfach an Stepanov denken:
I find OOP technically unsound. It attempts to decompose the world in terms of interfaces that vary on a single type. To deal with the real problems you need multisorted algebras - families of interfaces that span multiple types. I find OOP philosophically unsound. It claims that everything is an object. Even if it is true it is not very interesting - saying that everything is an object is saying nothing at all. I find OOP methodologically wrong. It starts with classes. It is as if mathematicians would start with axioms. You do not start with axioms - you start with proofs. Only when you have found a bunch of related proofs, can you come up with axioms. You end with axioms. The same thing is true in programming: you have to start with interesting algorithms. Only when you understand them well, can you come up with an interface that will let them work.
naja, das war jetzt OT - keine Stellungnahme zum Thema selbst.
-
CStoll schrieb:
Und ja, für Zustände gibt es in C++ kein eigenes Sprachmittel...
hat c++ keine variablen mehr

-
Undertaker schrieb:
CStoll schrieb:
Und ja, für Zustände gibt es in C++ kein eigenes Sprachmittel...
hat c++ keine variablen mehr

Das schon, aber Variablen hat sich Xin ja schon für Teilbeziehungen reserviert

-
CStoll schrieb:
Ein Fenster ist kein Zustand, sondern ein (mehr oder weniger) real existierendes Objekt. Ein Dialog ist eine spezielle Art von Fenster.
Und was bitte schön ist ein Objekt? Eine Zustandsbeschreibung für etwas, was mit einer Klasse klassifiziert wird.
Auto: rot, 195km/h Spitze, Benziner.
Window: Aktiviert, Position( x, y ).CStoll schrieb:
Und ja, für Zustände gibt es in C++ kein eigenes Sprachmittel (du hast deine Typerweiterungen für sowas entwickelt(?)).
Jedes Objekt ist eine Zustandsbeschreibung. Vom char bis hin zur komplexen Instanz, einschließlich Window.
Verschiebst Du das Fenster, ändert sich der Zustand des Objektes usw.Was die Typerweiterung angeht, ja, aber nicht für C++. In meinem Framework wächst nunmal auch meine Sprache heran und die unterstützt Flags direkt.
CStoll schrieb:
Wenn du einen int mit einer Maßeinheit versehen willst, um Strecken und Gewichte unterscheiden zu können, geht das in die richtige Richtung. Aber Hilfsklassen anlegen zu müssen, nur um einer Area zwei Maßzahlen übergeben zu können halte ich ein wenig übertrieben.
Ähh... moment... Du beklagst Dich, über die bei mir fehlende Unterscheidung WindowFlag und WindowFlags und jetzt wird's übertrieben, wenn ich Maßeinheiten klassifiziere?!
CStoll schrieb:
Und außerdem tendiert der Ansatz auf Dauer zu extrem langen Variablennamen (gerade wenn ich mehrere technisch ähnliche Klassen an verschiedenen Stellen des Programms verwenden will).
Mein Ansatz tendiert zu überhaupt keinen Variablennamen und vor allem tendiert er dazu "ähnliche" Klassen zu vermeiden.
CStoll schrieb:
Achja: Wie willst du auf diese Weise einen Bildfilter (hat zwei Bildbereiche und überträgt Daten von einem zum anderen) mit der DigiCam-Klasse zusammenarbeiten lassen
Witzigerweise ist das genau das, was ich im letzten Jahr mit besagtem Framework programmiert habe.
Ein BitMapFilter ist eine BitMap. Die Quelle wird per Konstruktor übergeben, anschließend kann man den Filter wie eine BitMap verwenden: sie auslesen, oder auch gefiltert darin zeichnen usw.
Und weil sich der Filter genauso verhält wie eine BitMap, kann man sie ebenso auf dem Bildschirm ausgeben, auf die Platte schreiben, oder z.B. an LabView exportieren, ohne sich Gedanken darüber zu machen, dass man eigentlich keine echte Bitmap in den Fingern hat.Nein, ich habe keine class SourceBitMap und class DestBitMap definiert. Ich sagte ja auch nicht, dass ich auf Membervariablen in der Programmierung verzichte. Ich sage lediglich, dass diese Technik durchaus sinnvoll ist.
CStoll schrieb:
Xin schrieb:
Das habe ich hier begründet: Gleiche Eigenschaften haben in den Klassen auch zwangsläufig gleiche Namen, weil sie über die Klasse und nicht über ein beliebig zu nennendes Member angesprochen werden.
Und im Ernstfall muß man die Eigenschaften dann doch wieder duplizieren - und hat neue Namen.
Es gibt keine gleichen Eigenschaften, die man duplizieren könnte. Es gibt nur genau einmal eine linke, obere Ecke, kein Fenster kann nicht zwei linke, obere Ecken haben. Und entsprechende Datentypen können das benennen.
CStoll schrieb:
Xin schrieb:
Und warum sollte ich mich da noch weiter in der Beweispflicht fühlen?
Du begründest ja auch nicht, warum Du davon ausgehst, dass Vererbung ausschließlich "ist-ein" bedeuten darf. Hast Du das "ausschließlich" mal in einem Buch gelesen? Hat der Autor das "ausschließlich" begründet? Und war der Grund erwähnenswert?
Die Begründung dürfte zu lang werden, um sie hier zu posten - du kannst sie aber gerne selber nachlesen:
Effektiv C++ programmieren | ISBN: 9783827313058Du willst auf Lektion 35 raus "Sorgen sie dafür, dass öffentliche Vererbung 'ist ein' bedeutet"?
Ich habe das Buch gelesen, sogar mit großem Interesse. Mein Buch enthält reihenweise Marker und PostIts und da wo die PostIts für meine Anmerkungen nicht reichten, liegen Zettel drin. Ich habe mich mit dem Buch auseinandergesetzt. Dein Rechteck <-> Quadrath kommt ja offenbar auch daraus.
Selbiges gilt auch für die Fortsetzung.Ich erzeuge keine Pinguine, denn meine Fenster können fliegen und ich erstelle auch keine Methoden, die sich in der Hirachie wieder ändern. Du möchtest eine idiotische Frage verhindern, bei mir mache ich das nicht.
Und nun?"Xin ignoriert Scott Meyers" oder "Xin macht unübliche Dinge"?
Ich ignoriere ihn nicht. Und meine Klasse widerspricht ihm nichtmals, ich habe kein Problem damit, einen operator bool() zu haben.
Dass ich über den operator bool() in C++ nicht glücklich bin, sagte ich auch schon. Ich bin mit "int Flags;" aber auch nicht glücklich. Besser kann ich es in C++ nicht ausdrücken und weil das bei vielen Punkten der Fall ist, begann ich eine eigene Sprache zu definieren, die unter anderem Flags besser unterstützt.
Bis dahin muss ich mit operator bool() leben.CStoll schrieb:
Du hast die Klassen geschrieben, also verstehst du auch das dahinterliegende Konzept. Andere Programmierer müssen erstmal das Konzept verstanden haben, bevor sie überhaupt daran gehen können, deine Zustands-Klassen einsetzen zu können.
(und wie du inzwischen bemerkt haben dürftest, widerspricht dein Konzept zumindest der "üblichen" Vorgehensweise)Die Klassen, die man verwendet zu verstehen, ist eine Grundvoraussetzung, um sie nutzen.
Dass ich nicht übliche Dinge mache, ist in Ordnung. Nicht übliche Dinge zu machen, spiegelt sich in meinen Arbeitszeugnissen mit Bemerkungen wie "Kreativität" und "vollsten Zufriedenheit" wieder.
Von daher kann ich damit leben.CStoll schrieb:
Xin schrieb:
Ich hab's für Dich verboten, bei mir ist es nicht verboten. Bei mir darf man auch idiotische Fragen stellen. Macht aber keiner. Also ein Window ist ein WindowFlag und ein Window erlaubt bei mir alles, was ein WindowFlag erlaubt.
So viel Disziplin - echt erstaunlich

Randfrage: Wieviele Leute arbeiten bisher mit deinem Framework?Nicht soviel, nur etwas. Nicht mehr als bei normalen Flags.
Ansonsten wußte ich, dass die Frage nach den Nutzern kommt. Es ist egal, wieviele es nutzen, es ist eh zu wenig, um zu sagen, dass es allgemeinverständlich ist. Es sind drei Personen. Der Rückschluss, dass es unverständlich wäre, weil es nur drei sind, ist nicht zulässig. Es benutzen drei Personen, weil nicht mehr Zugriff darauf haben.
Die Allergien schmeiße ich mal raus, die verlieren zusehens Bezug zum Thema.
CStoll schrieb:
Genauso: Bei der Verwendung "wnd.Flags|=Fullscreen;" oder "wnd.SetFlag(Fullscreen);" wird deutlich, daß ich einen Teilaspekt meiner Klasse ändere, bei "wnd|=Window::Fullscreen;" sieht man auf den ersten Blick zu eine Zuweisung und muß erstmal verstehen/nachsehen, was sie machen soll.1
Ich habe, es programmiert, logischerweise ist das für mich verständlich. Ich habe allerdings auch schon einiges an Sourcen gesehen, die man erstmal verstehen muss. Und ich muss ganz ehrlich sagen, für "wnd|=Window::Fullscreen", würde ich keine Doku aufschlagen. Ich sehe das als selbsterklärend, selbst wenn da nicht WindowFlags::Fullscreen steht.
CStoll schrieb:
Undertaker schrieb:
CStoll schrieb:
Und ja, für Zustände gibt es in C++ kein eigenes Sprachmittel...
hat c++ keine variablen mehr

Das schon, aber Variablen hat sich Xin ja schon für Teilbeziehungen reserviert

Mit dem 'Smiley' können wir das hier ja einstellen, oder?
-
Xin schrieb:
Und was bitte schön ist ein Objekt? Eine Zustandsbeschreibung für etwas, was mit einer Klasse klassifiziert wird.
Ein Objekt ist eine Zustandsbeschreibung?

Außerdem: Was sind denn nun Flags?
-
scrub schrieb:
Xin schrieb:
Und was bitte schön ist ein Objekt? Eine Zustandsbeschreibung für etwas, was mit einer Klasse klassifiziert wird.
Ein Objekt ist eine Zustandsbeschreibung?

|:-\
Soweit zu den grundlegenden Konzepten der Informatik.Die Realität im Computer ist eine Zustandsbeschreibung.
Objekte existieren im Computer. Eine Instanz von class Auto ist deswegen aber kein Auto, sondern bestenfalls die Beschreibung eines Autos und stellt den Zustand eines imaginären Autos dar. Das Auto, das beschrieben wird, ist rot, fährt mit 60km/h und fährt vorwärts im 4. Gang. Das ist der Zustand des imaginären Autos.Bei simulierten Crash-Tests, lässt man Objekte nicht wirklich aufeinander prallen

scrub schrieb:
Außerdem: Was sind denn nun Flags?
Kann mir kaum vorstellen, dass Frage ernstgemeint ist... aber gut... die Hoffnung stirbt zuletzt.
Ein Flag ist die Antwort auf eine Ja/Nein Frage. bool Fullscreen? Ja oder Nein. bool Schwanger? Ja oder Nein.
Flagge schwenken oder Flagge nicht schwenken.
Häufig hat man nicht nur eine solcher Flaggen, sondern eine ganze Reihe: Flags.
Wie man diese nun im einzelnen implementiert, spielt dabei eigentlich keine Rolle.
Doch es bietet sich an, viele dieser Ja/Nein-Fragen in einen Datentyp zu komprimieren, statt viele bool-Variablen zu verwenden. Und ob man das nun mit einer int-Variablen irgendwie macht oder wie ich in einer dafür geschriebenen Flags-Klasse, spielt für die Frage "Was sind denn nun Flags?" auch keine Rolle.
-
Xin schrieb:
Doch es bietet sich an, viele dieser Ja/Nein-Fragen in einen Datentyp zu komprimieren, statt viele bool-Variablen zu verwenden.
wenn ihr das schon mit klassen macht: ich würde diese komprimierung dann vor'm benutzer verstecken, so dass es aus seiner sicht wirklich alle flags unabhängig sind.
nicht dass er aus versehen schreiben kann 'flags = 5' und damit 2 setzt und alle anderen löscht.

-
Mal abgesehen von der Verwendung der Operatoren, mir geht es hier rein um die Vererbung.
Vererbung ist durch Polymorphie meist eine komplexere Architektur als eine einfache Komposition.
Eine Klasse WindowFlags, welche man z.B. dem Konstruktor der Klasse Window übergeben kann halte ich für vielseitiger und einfacher zu berücksichtigen.
Zudem kann man so Attribute / Flags richtig kapseln und trennt sie komplett von der eigentlichen Klasse. Die Variante der Vererbung würde die Flags zwar optisch trennen, dann aber wieder in die eigentliche Klasse vererben, was die üblichen Probleme mit sich bringen kann, Variablennamen, etc.Ich frage mich also: was spricht überhaupt für die Variante der Vererbung und gegen die Variante der Komposition?
-
Tellerrand schrieb:
Ich frage mich also: was spricht überhaupt für die Variante der Vererbung und gegen die Variante der Komposition?
CStoll und ich kamen vor ein paar Seiten zu dem Schluss, dass die Komposition in C++ die sinnvollste Variante zu sein scheint. Nur zum Schluss der Diskussion kamen wir offensichtlich noch nicht.

-
Womit die Frage "Was spricht für die Vererbung" mal wieder nicht beantwortet wurde.
-
Theston schrieb:
Womit die Frage "Was spricht für die Vererbung" mal wieder nicht beantwortet wurde.
Da die Frage vermutlich an mich gerichtet ist, kann ich dazu nur betonen, dass die Frage ist ausführlich beantwortet wurde. Wenn Du eine Detailfrage hast, beantworte ich die gerne, aber wir fangen nicht wieder bei 50 Seiten lang bei 0 an. Dafür ist mir die Zeit zu schade. Jeder darf gerne den Thread durchlesen und ich bin hier nicht als Quote-Service engagiert.
-
Die letzten ~50 Seiten hast du nur erklärt, warum "das Schlechte" an deinem Model nicht völlig schlecht ist.
Aber ich hatte auch keine andere Antwort erwartet
-
Xin schrieb:
CStoll schrieb:
Ein Fenster ist kein Zustand, sondern ein (mehr oder weniger) real existierendes Objekt. Ein Dialog ist eine spezielle Art von Fenster.
Und was bitte schön ist ein Objekt? Eine Zustandsbeschreibung für etwas, was mit einer Klasse klassifiziert wird.
Auto: rot, 195km/h Spitze, Benziner.
Window: Aktiviert, Position( x, y ).So langsam blicke ich durch deine Sichtweise durch - aber die scheint weniger objektorientiert zu sein, sondern datenorientiert.
OK, was ist ein "Objekt"? Ein Objekt ist ein Gegenstand, mit dem ich interagieren kann. In das Auto kann ich einsteigen, auf's Gaspedal treten oder auf den Tacho schauen (und wenn ich nicht aufpasse, es auch in der nächsten Mauer parken), das Fenster kann ich anklicken oder ihm verschiedene Tastenkombinationen schicken. Zustände sind da eher zweitrangig und gehören zu den Interna des Objekts - nach außen wirken sie sich nur dadurch aus, daß das Objekt anders auf meine Aktionen reagiert.
(und wie ein Zustand intern dargestellt wird, ist für mich als Klassennutzer auch irrelevant - das Auto könnte seine Maximalgeschwindigkeit direkt als double speichern, über physikalische Berechnungen aus der Leistungskurve seines Motors ermitteln oder auch aus einer Datenbank des Herstellers abfragen - aber was es macht, ist Entscheidung des Autos und nicht der Maximalgeschwindigkeit)
Xin schrieb:
Was die Typerweiterung angeht, ja, aber nicht für C++. In meinem Framework wächst nunmal auch meine Sprache heran und die unterstützt Flags direkt.
Schön, wenn du eine Sprache hast, die zwischen Zuständen und Teilobjekten unterscheiden kann. C++ kann das leider nicht, also brauchst du gar nicht versuchen, es dazu zu bringen.
Xin schrieb:
CStoll schrieb:
Wenn du einen int mit einer Maßeinheit versehen willst, um Strecken und Gewichte unterscheiden zu können, geht das in die richtige Richtung. Aber Hilfsklassen anlegen zu müssen, nur um einer Area zwei Maßzahlen übergeben zu können halte ich ein wenig übertrieben.
Ähh... moment... Du beklagst Dich, über die bei mir fehlende Unterscheidung WindowFlag und WindowFlags und jetzt wird's übertrieben, wenn ich Maßeinheiten klassifiziere?!
Ein Unterschied zwischen Zahl und Zahl mit Maßeinheit ist klar, aber den kannst du nicht vernünftig mit Vererbung nachbauen (wenn alle Maßgrößen von int abgeleitet werden, kannst du auch alle Maßgrößen als nackte int's behandeln - und damit auch beliebig miteinander verrechnen. Und erzähl mir blos nicht, daß du eine Addition von Gewicht+Länge auf dieser Basis verhindern kannst.
Was ich an dem oberen Ansatz bemängle, ist zum Beispiel die Unterscheidung von PixelWidth und PixelHeight - beide Typen sind technisch gleichwertig und wurden nur eingeführt, damit Area zwei Pixelmaße in sich vereinigen kann.
Xin schrieb:
CStoll schrieb:
Und außerdem tendiert der Ansatz auf Dauer zu extrem langen Variablennamen (gerade wenn ich mehrere technisch ähnliche Klassen an verschiedenen Stellen des Programms verwenden will).
Mein Ansatz tendiert zu überhaupt keinen Variablennamen und vor allem tendiert er dazu "ähnliche" Klassen zu vermeiden.
OK, dann eben zu Klassennamen.
Xin schrieb:
CStoll schrieb:
Achja: Wie willst du auf diese Weise einen Bildfilter (hat zwei Bildbereiche und überträgt Daten von einem zum anderen) mit der DigiCam-Klasse zusammenarbeiten lassen
Witzigerweise ist das genau das, was ich im letzten Jahr mit besagtem Framework programmiert habe.
Ein BitMapFilter ist eine BitMap. Die Quelle wird per Konstruktor übergeben, anschließend kann man den Filter wie eine BitMap verwenden: sie auslesen, oder auch gefiltert darin zeichnen usw.
Und weil sich der Filter genauso verhält wie eine BitMap, kann man sie ebenso auf dem Bildschirm ausgeben, auf die Platte schreiben, oder z.B. an LabView exportieren, ohne sich Gedanken darüber zu machen, dass man eigentlich keine echte Bitmap in den Fingern hat.Und schon hast du eine Asymmetrie in deinem Design - die Quelle ist ein Member, die Senke nicht. Und wenn du Filter mit mehreren Ausgängen hast, wird das Design unüberschaubar (entweder du splittest den Filter in zwei Teile auf, die die identischen Berechnungen duplizieren, du fügst eine Zwischenklasse "zwei Areas" als Ausgang und zwei Splitter zum Zerlegen dieser Klasse ein oder zwei Hilfsklassen "TargetArea1" und "TargetArea2", von denen der Filter abgeleitet wird.
Xin schrieb:
CStoll schrieb:
Xin schrieb:
Das habe ich hier begründet: Gleiche Eigenschaften haben in den Klassen auch zwangsläufig gleiche Namen, weil sie über die Klasse und nicht über ein beliebig zu nennendes Member angesprochen werden.
Und im Ernstfall muß man die Eigenschaften dann doch wieder duplizieren - und hat neue Namen.
Es gibt keine gleichen Eigenschaften, die man duplizieren könnte. Es gibt nur genau einmal eine linke, obere Ecke, kein Fenster kann nicht zwei linke, obere Ecken haben. Und entsprechende Datentypen können das benennen.
Ein Fenster hat eine linke obere Ecke, eine rechte untere Ecke und noch viele Punkte dazwischen - um jeden von denen ansprechen zu können, brauchst du entsprechend viele Zwischenklassen, die der Klasse "Punkt" jeweils einen neuen Namen geben. Außerdem interessiert es mich als Außenstehenden nicht, ob das Fenster nun zwei Ecken, Ecke+Größe oder Mittelpunkt+Größe intern verwaltet - ich interessiere mich nur danach, bei Bedarf jede Ecke oder den Mittelpunkt ansprechen zu können.
Xin schrieb:
CStoll schrieb:
Xin schrieb:
Und warum sollte ich mich da noch weiter in der Beweispflicht fühlen?
Du begründest ja auch nicht, warum Du davon ausgehst, dass Vererbung ausschließlich "ist-ein" bedeuten darf. Hast Du das "ausschließlich" mal in einem Buch gelesen? Hat der Autor das "ausschließlich" begründet? Und war der Grund erwähnenswert?
Die Begründung dürfte zu lang werden, um sie hier zu posten - du kannst sie aber gerne selber nachlesen:
Effektiv C++ programmieren | ISBN: 9783827313058Du willst auf Lektion 35 raus "Sorgen sie dafür, dass öffentliche Vererbung 'ist ein' bedeutet"?
Ich habe das Buch gelesen, sogar mit großem Interesse. Mein Buch enthält reihenweise Marker und PostIts und da wo die PostIts für meine Anmerkungen nicht reichten, liegen Zettel drin. Ich habe mich mit dem Buch auseinandergesetzt. Dein Rechteck <-> Quadrath kommt ja offenbar auch daraus.
Selbiges gilt auch für die Fortsetzung.Ich erzeuge keine Pinguine, denn meine Fenster können fliegen und ich erstelle auch keine Methoden, die sich in der Hirachie wieder ändern. Du möchtest eine idiotische Frage verhindern, bei mir mache ich das nicht.
Und nun?"Xin ignoriert Scott Meyers" oder "Xin macht unübliche Dinge"?
Ich ignoriere ihn nicht. Und meine Klasse widerspricht ihm nichtmals, ich habe kein Problem damit, einen operator bool() zu haben.
Dass ich über den operator bool() in C++ nicht glücklich bin, sagte ich auch schon. Ich bin mit "int Flags;" aber auch nicht glücklich. Besser kann ich es in C++ nicht ausdrücken und weil das bei vielen Punkten der Fall ist, begann ich eine eigene Sprache zu definieren, die unter anderem Flags besser unterstützt.
Bis dahin muss ich mit operator bool() leben.Es ist vom Design egal, ob der operator bool() nun technisch gesichert ist oder nur durch eine Konvention. Fakt ist, daß es keinen Sinn macht, ein Fenster als bool zu interpretieren - und damit verhält es sich nicht wie ein Flag.
(übrigens taucht das Rechteck<->Quadrat Beispiel nicht nur bei Meyers auf)
Xin schrieb:
CStoll schrieb:
Du hast die Klassen geschrieben, also verstehst du auch das dahinterliegende Konzept. Andere Programmierer müssen erstmal das Konzept verstanden haben, bevor sie überhaupt daran gehen können, deine Zustands-Klassen einsetzen zu können.
(und wie du inzwischen bemerkt haben dürftest, widerspricht dein Konzept zumindest der "üblichen" Vorgehensweise)Die Klassen, die man verwendet zu verstehen, ist eine Grundvoraussetzung, um sie nutzen.
Dass ich nicht übliche Dinge mache, ist in Ordnung. Nicht übliche Dinge zu machen, spiegelt sich in meinen Arbeitszeugnissen mit Bemerkungen wie "Kreativität" und "vollsten Zufriedenheit" wieder.
Von daher kann ich damit leben.Dann mußt du auch damit leben, daß andere Programmierer deine Sichtweise nicht auf Anhieb verstehen.
Xin schrieb:
CStoll schrieb:
Xin schrieb:
Ich hab's für Dich verboten, bei mir ist es nicht verboten. Bei mir darf man auch idiotische Fragen stellen. Macht aber keiner. Also ein Window ist ein WindowFlag und ein Window erlaubt bei mir alles, was ein WindowFlag erlaubt.
So viel Disziplin - echt erstaunlich

Randfrage: Wieviele Leute arbeiten bisher mit deinem Framework?Nicht soviel, nur etwas. Nicht mehr als bei normalen Flags.
"Normale" Flags sind sehr sehr weit verbreitet

Xin schrieb:
Ansonsten wußte ich, dass die Frage nach den Nutzern kommt. Es ist egal, wieviele es nutzen, es ist eh zu wenig, um zu sagen, dass es allgemeinverständlich ist. Es sind drei Personen. Der Rückschluss, dass es unverständlich wäre, weil es nur drei sind, ist nicht zulässig. Es benutzen drei Personen, weil nicht mehr Zugriff darauf haben.
Die Anzahl der Nutzer sagt nichts über die Verständlichkeit aus, da magst du Recht haben. Aber die Tatsache, daß du hier der einzige bist, der den Ansatz sinnvoll findet, sollte dir schon zu Denken geben

Xin schrieb:
Die Allergien schmeiße ich mal raus, die verlieren zusehens Bezug zum Thema.
Den Bezug hast du doch selber angefangen.
Xin schrieb:
CStoll schrieb:
Genauso: Bei der Verwendung "wnd.Flags|=Fullscreen;" oder "wnd.SetFlag(Fullscreen);" wird deutlich, daß ich einen Teilaspekt meiner Klasse ändere, bei "wnd|=Window::Fullscreen;" sieht man auf den ersten Blick zu eine Zuweisung und muß erstmal verstehen/nachsehen, was sie machen soll.1
Ich habe, es programmiert, logischerweise ist das für mich verständlich. Ich habe allerdings auch schon einiges an Sourcen gesehen, die man erstmal verstehen muss. Und ich muss ganz ehrlich sagen, für "wnd|=Window::Fullscreen", würde ich keine Doku aufschlagen. Ich sehe das als selbsterklärend, selbst wenn da nicht WindowFlags::Fullscreen steht.
Du siehst es als selbsterklärend, weil du das Konzept durchschaut hast. Für mich ist dieser Ausdruck z.B. nicht selbsterklärend.
Xin schrieb:
CStoll schrieb:
Undertaker schrieb:
CStoll schrieb:
Und ja, für Zustände gibt es in C++ kein eigenes Sprachmittel...
hat c++ keine variablen mehr

Das schon, aber Variablen hat sich Xin ja schon für Teilbeziehungen reserviert

Mit dem 'Smiley' können wir das hier ja einstellen, oder?
OK, dann anders - andere Sprachen mögen eine Unterscheidung zwischen Zuständen des Objekts und Teilobjekten bieten - C++ stellt beides durch Member dar (daß das nicht die perfekte Lösung ist, sehe ich ein). Du bist anscheinend der Meinung, dort einen syntaktischen Unterschied zu benötigen - und wirfst darum Zustände mit Verwandschaftsbeziehungen in einen Topf.
Tellerrand schrieb:
Ich frage mich also: was spricht überhaupt für die Variante der Vererbung und gegen die Variante der Komposition?
Da muß ich meinen Vorrednern Recht geben - du hast weder ein Argument geliefert, warum die Komposition ungeeignet wäre, noch eins für die Überlegenheit deines Vererbungsansatzes. Auf den letzten Seiten hast du nur versucht, Argumente gegen deinen Ansatz zu entkräften (und damit dein Grundprinzip wieder verwässert).
-
heutige PCs sind keine Turingmaschienen, also ist auch die zustandslogik fehl am Platz. Nimm als Beispiel einen streambuffer der iostream lib. Dieser speichert daten in einem char array oder string. ist dieses char array aber ein Zustand? nein, sicherlich nicht. Ein Zustand wäre, wenn das array leer wäre, denn dann würde der puffer beim nächsten lesen eof zurückgeben. Aber das ist nur die interpretation der daten des arrays(bzw des zeigers auf die aktuelle position des arrays).
-
otze schrieb:
heutige PCs sind keine Turingmaschienen, also ist auch die zustandslogik fehl am Platz.
Sondern?
Nimm als Beispiel einen streambuffer der iostream lib. Dieser speichert daten in einem char array oder string. ist dieses char array aber ein Zustand?
nein, sicherlich nicht.Begründung? Es ist *offensichtlich* ein Zustand.
-
otze schrieb:
heutige PCs sind keine Turingmaschienen, also ist auch die zustandslogik fehl am Platz. ...
Objekte haben ohnehin nichts mit dem Entscheidungsproblem oder speziell mit
Sprachen, Berechenbarkeit oder Komplexitaet zu tun.gruss
v R
-
post nr 101 - wer hätte das gedacht, 2 xin-troll-threads in einem monat

-
CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Ein Fenster ist kein Zustand, sondern ein (mehr oder weniger) real existierendes Objekt. Ein Dialog ist eine spezielle Art von Fenster.
Und was bitte schön ist ein Objekt? Eine Zustandsbeschreibung für etwas, was mit einer Klasse klassifiziert wird.
Auto: rot, 195km/h Spitze, Benziner.
Window: Aktiviert, Position( x, y ).So langsam blicke ich durch deine Sichtweise durch - aber die scheint weniger objektorientiert zu sein, sondern datenorientiert.
Datenorientiert? Klassenorientiert.
Egal. Daten - Klasseninstanzen - alles Objekte.Was ich amüsant finde ist, wie sich viele an dem Wort "objekt" festklammern, als ob es eine wichtige Bedeutung hätte. Warum programmiert man denn, weil es soviel Spaß macht, oder weil man Daten miteinander verwursten will?
CStoll schrieb:
OK, was ist ein "Objekt"? Ein Objekt ist ein Gegenstand, mit dem ich interagieren kann. In das Auto kann ich einsteigen, auf's Gaspedal treten oder auf den Tacho schauen (und wenn ich nicht aufpasse, es auch in der nächsten Mauer parken), das Fenster kann ich anklicken oder ihm verschiedene Tastenkombinationen schicken. Zustände sind da eher zweitrangig und gehören zu den Interna des Objekts - nach außen wirken sie sich nur dadurch aus, daß das Objekt anders auf meine Aktionen reagiert.
(und wie ein Zustand intern dargestellt wird, ist für mich als Klassennutzer auch irrelevant - das Auto könnte seine Maximalgeschwindigkeit direkt als double speichern, über physikalische Berechnungen aus der Leistungskurve seines Motors ermitteln oder auch aus einer Datenbank des Herstellers abfragen - aber was es macht, ist Entscheidung des Autos und nicht der Maximalgeschwindigkeit)
Du widersprichst Dir grade.
Wichtig ist, dass es nach außen als Ganzes funktioniert. Ob die class VMax oder das class Car selbst die Maximalgeschwindigkeit verwaltet, ist ein Interna der Klasse Car. Es muss also kein Member sein.CStoll schrieb:
Schön, wenn du eine Sprache hast, die zwischen Zuständen und Teilobjekten unterscheiden kann. C++ kann das leider nicht, also brauchst du gar nicht versuchen, es dazu zu bringen.
Super Einstellung. "Ich" kann das nicht, also brauchst "Du" es nicht zu versuchen.
Ich versuche es trotzdem. Sich derart dagegen zu wehren bringt aber nix, ich zwinge schließlich niemanden hier, es zu nutzen.CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Wenn du einen int mit einer Maßeinheit versehen willst, um Strecken und Gewichte unterscheiden zu können, geht das in die richtige Richtung. Aber Hilfsklassen anlegen zu müssen, nur um einer Area zwei Maßzahlen übergeben zu können halte ich ein wenig übertrieben.
Ähh... moment... Du beklagst Dich, über die bei mir fehlende Unterscheidung WindowFlag und WindowFlags und jetzt wird's übertrieben, wenn ich Maßeinheiten klassifiziere?!
Ein Unterschied zwischen Zahl und Zahl mit Maßeinheit ist klar, aber den kannst du nicht vernünftig mit Vererbung nachbauen (wenn alle Maßgrößen von int abgeleitet werden, kannst du auch alle Maßgrößen als nackte int's behandeln
Kilo AddiereGewichte( Kilo a, Kilo b ) { return a+b; }
Dann übergib da mal ein int.CStoll schrieb:
und damit auch beliebig miteinander verrechnen. Und erzähl mir blos nicht, daß du eine Addition von Gewicht+Länge auf dieser Basis verhindern kannst.
Warum sollte ich das verhindern?
4kg und 7m. Wenn ich die Zahl des Gewichts mit der Zahl der Länge addiere, erhalte ich 11. Ist doch eine legitime Fragestellung. Was immer man mit der Zahl anfangen will. Was ich nicht erhalte sind 11 Kilometer oder derartiges.Ich kann eine Zuweisung auf Kilo oder auf Meter verhindern.
Ich kann aber zum Beispiel 7m * 8m berechnen. Daraus ergeben sich Meter2, die ich nicht auf eine Metervariable zuweisen kann.
Operatorüberladung ist das Zauberwort, freundlich kombiniert mit "explizit".CStoll schrieb:
Was ich an dem oberen Ansatz bemängle, ist zum Beispiel die Unterscheidung von PixelWidth und PixelHeight - beide Typen sind technisch gleichwertig und wurden nur eingeführt, damit Area zwei Pixelmaße in sich vereinigen kann.
Okay, das bemängelst Du mit einer technsich falschen Begründung. Sie sind eben nicht technisch gleichwertig, weil - wie der Name schon sagt - das eine ist eine Breite und das andere eine Höhe. Und wenn Du ein Schiff konstruierst und dabei Breite und Höhe gleichwertig, also austauschbar machst, dann könnte es sein, dass das Schiff recht merkwürdig aussieht.
Werte müssen klassifiziert werden - entweder durch die Disziplin des Entwicklers - oder durch Klassen, deren Zweck es ist, Werte zu klassifizieren.CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Und außerdem tendiert der Ansatz auf Dauer zu extrem langen Variablennamen (gerade wenn ich mehrere technisch ähnliche Klassen an verschiedenen Stellen des Programms verwenden will).
Mein Ansatz tendiert zu überhaupt keinen Variablennamen und vor allem tendiert er dazu "ähnliche" Klassen zu vermeiden.
OK, dann eben zu Klassennamen.
Hmm... Point, Area, BitMap, Soucetext, XMLEntity. Das sind keine lange Klassennamen.
Ansonsten bietet C++ auch Namespaces, von denen ich rege Gebrauch mache.CStoll schrieb:
Und schon hast du eine Asymmetrie in deinem Design - die Quelle ist ein Member, die Senke nicht. Und wenn du Filter mit mehreren Ausgängen hast, wird das Design unüberschaubar (entweder du splittest den Filter in zwei Teile auf, die die identischen Berechnungen duplizieren,
Überlege Dir mal kurz, was ein Filter ist. Einen Filter setzt man zum Beispiel in einen Laserstrahl, vorne kommt was rein, hinten kommt was raus. Du veränderst den Typ aber nicht. Es geht Licht rein und es kommt Licht raus.
Was Du kritisierst, ist kein Filter, sondern ein Adapter. Ergo falsche Kritik zu falschem Problem.
Das Design halte ich für optimal für einen Filter.Weiterhin duplizierst du keine Berechnungen, dafür gibt es notfalls templates, wenn Du das schon so lösen möchtest.
CStoll schrieb:
du fügst eine Zwischenklasse "zwei Areas" als Ausgang und zwei Splitter zum Zerlegen dieser Klasse ein oder zwei Hilfsklassen "TargetArea1" und "TargetArea2", von denen der Filter abgeleitet wird.
Gut, bauen wir einen Adapter auf, der zwei TargetAreas hat, die natürlich nicht TargetArea heißen würden. Nehmen wir unser Fenster und adaptieren es auf vier Punkte, die dann ObenLinks, UntenRechts usw.. heißen würden und direkt übertragbar für andere Objekte wären.
Und? Hättest Du ein Problem damit?
CStoll schrieb:
Ein Fenster hat eine linke obere Ecke, eine rechte untere Ecke und noch viele Punkte dazwischen - um jeden von denen ansprechen zu können, brauchst du entsprechend viele Zwischenklassen, die der Klasse "Punkt" jeweils einen neuen Namen geben. Außerdem interessiert es mich als Außenstehenden nicht, ob das Fenster nun zwei Ecken, Ecke+Größe oder Mittelpunkt+Größe intern verwaltet - ich interessiere mich nur danach, bei Bedarf jede Ecke oder den Mittelpunkt ansprechen zu können.
Und? Hindere ich Dich oder die Verwendung von Klassifizierungen daran?
CStoll schrieb:
Xin schrieb:
-Scott Meyers - Effiziente C++ Programmierung -
Dein Rechteck <-> Quadrath kommt ja offenbar auch daraus.
Selbiges gilt auch für die Fortsetzung.Ich erzeuge keine Pinguine, denn meine Fenster können fliegen und ich erstelle auch keine Methoden, die sich in der Hirachie wieder ändern. Du möchtest eine idiotische Frage verhindern, bei mir mache ich das nicht.
Und nun?"Xin ignoriert Scott Meyers" oder "Xin macht unübliche Dinge"?
Ich ignoriere ihn nicht. Und meine Klasse widerspricht ihm nichtmals, ich habe kein Problem damit, einen operator bool() zu haben.
Dass ich über den operator bool() in C++ nicht glücklich bin, sagte ich auch schon. Ich bin mit "int Flags;" aber auch nicht glücklich. Besser kann ich es in C++ nicht ausdrücken und weil das bei vielen Punkten der Fall ist, begann ich eine eigene Sprache zu definieren, die unter anderem Flags besser unterstützt.
Bis dahin muss ich mit operator bool() leben.Es ist vom Design egal, ob der operator bool() nun technisch gesichert ist oder nur durch eine Konvention.
Fakt ist, daß es keinen Sinn macht, ein Fenster als bool zu interpretieren - und damit verhält es sich nicht wie ein Flag.Es verhält sich wie WindowFlags. Nicht, wie ein Flag. Immernoch...
CStoll schrieb:
(übrigens taucht das Rechteck<->Quadrat Beispiel nicht nur bei Meyers auf)
Stimmt, aber solange es nicht im Zusammenhang mit der Problematik steht, juckt mich das auch nicht.
CStoll schrieb:
Dann mußt du auch damit leben, daß andere Programmierer deine Sichtweise nicht auf Anhieb verstehen.
Dieser Thread hat mich bisher nicht umgebracht.
Ich zwinge Dich nicht, Deine Daten zu klassifizieren. Ich habe kein Problem mit Membervariablen, ich sehe nur zusätzlich auch Alternativen. Ich habe hier nichts, was mir das Leben schwer macht.
Wenn Du eine alternative Sichtweise nicht auf Anhieb verstehst, wüßte ich jetzt nicht, wieso ich damit nicht leben könnte.CStoll schrieb:
Xin schrieb:
Nicht soviel, nur etwas. Nicht mehr als bei normalen Flags.
"Normale" Flags sind sehr sehr weit verbreitet

Bild und Express verkaufen sich auch sehr gut.
Und mit beiden kann man sehr gut Fenster putzen, wenn man sie auf Druckpapier castet und sich nicht auf das Interface "Schmierblatt" beschränkt.CStoll schrieb:
Xin schrieb:
Die Allergien schmeiße ich mal raus, die verlieren zusehens Bezug zum Thema.
Den Bezug hast du doch selber angefangen.
Ich sagte, dass ein Nussallergiker nicht auf einer Nusspackung darauf hingewiesen werden, dass sie für Nussallergiker nicht geeignet sind. Denken als Grundvoraussetzung. Deine Allergien oder die Deiner Oma interessieren mich in dem Thread nicht.
CStoll schrieb:
Xin schrieb:
Ich sehe das als selbsterklärend, selbst wenn da nicht WindowFlags::Fullscreen steht.
Du siehst es als selbsterklärend, weil du das Konzept durchschaut hast. Für mich ist dieser Ausdruck z.B. nicht selbsterklärend.
Dann solltest Du Dir überlegen, weitere Erfahrungen zu sammeln, statt Dich weiteren Erfahrungen nur zu widersetzen.
CStoll schrieb:
OK, dann anders - andere Sprachen mögen eine Unterscheidung zwischen Zuständen des Objekts und Teilobjekten bieten - C++ stellt beides durch Member dar (daß das nicht die perfekte Lösung ist, sehe ich ein).
Dann sieh bitte auch ein, dass C++ beides auch durch Vererbung anbietet und dass das auch nicht immer die perfekte Lösung ist. Trotzdem geht es.
CStoll schrieb:
Du bist anscheinend der Meinung, dort einen syntaktischen Unterschied zu benötigen - und wirfst darum Zustände mit Verwandschaftsbeziehungen in einen Topf.
...? Lies Dir den Satz nochmal durch...
CStoll schrieb:
Tellerrand schrieb:
Ich frage mich also: was spricht überhaupt für die Variante der Vererbung und gegen die Variante der Komposition?
Da muß ich meinen Vorrednern Recht geben - du hast weder ein Argument geliefert, warum die Komposition ungeeignet wäre,
Das könnte zum Beispiel daran liegen, dass ich die ganze Zeit betone, dass sie nicht ungeeignet ist...
CStoll schrieb:
noch eins für die Überlegenheit deines Vererbungsansatzes.
Das wiederum könnte daran liegen, dass ich nicht von "Überlegenheit" spreche, sondern von Alternative.
CStoll schrieb:
Auf den letzten Seiten hast du nur versucht, Argumente gegen deinen Ansatz zu entkräften (und damit dein Grundprinzip wieder verwässert).
Keine Ahnung, was Du als Verwässerung ansiehst. Eigentlich habe ich auf den letzten Seiten nur versucht, Dir zu zeigen, dass es Alternativen gibt, die auch Vorteile bieten - eben die Typsicherheit. Darum baue Flags in Klassen ein. Und hier kann man Typen vererbend zusammenbringen, ohne Mehrdeutigkeiten zu erhalten (wobei C++ bei Mehrfachvererbung verlangt, dass man in der abgeleiten Klasse using verwendet - es geht also doch wunderbar).
Vielleicht fällt Dir an der Tatsache, dass ich das mit der Mehrfachvererbung erst jetzt herausgefunden habe, auch auf, dass es sich hier nicht um "mein Grundprinzip" handelt und erst recht nicht um ein "Grundprinzip". Ich benutze Vererbung gelegentlich, um wiederverwertete Eigenschaften zu übertragen, aber das ist deswegen kein Grundprinzip (vgl. selbst da: Auto != Autositze).
Ich habe die Fürsprache für die Idee übernommen, die ich - je länger wir hier diskutieren - für immer besser halte. Du rennst gegen die Idee an, in einer Form, die ich mit "Hauptsache dagegen" am besten beschrieben sehe.
Und schau Dir Dein Posting mal an: Das meiste ist Geblubber, am Thema vorbei, subjektive Ablehnung, viel Konkretes kommt da auch nicht. Die Paprikaallergie Deiner Oma als Highlight. Darauf kann ich nicht argumentieren, sondern nur fragen, wo Du da ein Problem siehst. Und so liest Du hier mehrfach "Und?", weil mir der Zusammenhang mit dem Thema fehlt oder das Argument eben ist, dass Du es nicht auf Anhieb verstehst und andere es nicht benutzen. Das ist doch kein Argument, mal Alternativen auszuprobieren?!
Der einzige, der konkret was gebracht hat war Shade of Mine, was ich leider zu spät erst begriffen habe. Den Punkt halte ich für wichtig, aber nicht für so wichtig, dass ich auf die Typsicherheit verzichten würde. Zumal man den Punkt weiterhin durch genauere Klassifizierung in WindowFlags und WindowFlag ausräumen könnte.Bloß nicht gucken, ob da vielleicht ein Vorteil drin verborgen sein könnte. Ich beschäftige mich neutral damit: Komposition gut, Vererbung - auch nicht schlecht.
Das "Komposition gut" fällt Dir überhaupt nicht auf, oder? Das ist nichts, wo Du dagegen sein könntest.
Noch striktere Klassifizierung erforderlich? Sehr gut, weil Disziplin zwangsverordnet.Ich führe hier keinen Wettstreit gut gegen böse. Es geht hier um eine Alternative. Gut gegen genauso gut. Vielleicht gut gegen nicht ganz so gut in C++. Vielleicht auch gut gegen etwas besser, wenn man sich damit auseinandersetzt. Ich habe damit nur begrenzte Erfahrung, ich leite nicht grundsätzlich ab. Ich leite nur ein Objekt von seinen Flags ab und überlege, ob ich neue Klassen aus Vorhandenen sinnvoll zusammenvererben kann. Was mir nicht sinnvoll erscheint, kommt als Member rein.
otze schrieb:
heutige PCs sind keine Turingmaschienen, also ist auch die zustandslogik fehl am Platz.
OMG, genau sowas fehlte hier noch... geballte Kompetenz als Behauptung verpackt und auch noch öffentlich ausgesprochen.
Benutzername: schrieb:
post nr 101 - wer hätte das gedacht, 2 xin-troll-threads in einem monat

Und alle Unregistrierten sind auch schon da. Damit ist das Niveau des Threads gesichert.
CStoll, wenn Du von "Ich bin dagegen" auf "Ich bin nicht zwangsläufig dagegen" runterschalten kannst und diskutieren möchtest - meine E-Mailadresse findet sich auf meiner Homepage. Hier fällt grade der Forums-Kindergarten ein und sollte dem so sein, hab' ich da keine Lust drauf.
-
Xin schrieb:
CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Ein Fenster ist kein Zustand, sondern ein (mehr oder weniger) real existierendes Objekt. Ein Dialog ist eine spezielle Art von Fenster.
Und was bitte schön ist ein Objekt? Eine Zustandsbeschreibung für etwas, was mit einer Klasse klassifiziert wird.
Auto: rot, 195km/h Spitze, Benziner.
Window: Aktiviert, Position( x, y ).So langsam blicke ich durch deine Sichtweise durch - aber die scheint weniger objektorientiert zu sein, sondern datenorientiert.
Datenorientiert? Klassenorientiert.
Egal. Daten - Klasseninstanzen - alles Objekte.Was ich amüsant finde ist, wie sich viele an dem Wort "objekt" festklammern, als ob es eine wichtige Bedeutung hätte. Warum programmiert man denn, weil es soviel Spaß macht, oder weil man Daten miteinander verwursten will?
CStoll schrieb:
OK, was ist ein "Objekt"? Ein Objekt ist ein Gegenstand, mit dem ich interagieren kann. In das Auto kann ich einsteigen, auf's Gaspedal treten oder auf den Tacho schauen (und wenn ich nicht aufpasse, es auch in der nächsten Mauer parken), das Fenster kann ich anklicken oder ihm verschiedene Tastenkombinationen schicken. Zustände sind da eher zweitrangig und gehören zu den Interna des Objekts - nach außen wirken sie sich nur dadurch aus, daß das Objekt anders auf meine Aktionen reagiert.
(und wie ein Zustand intern dargestellt wird, ist für mich als Klassennutzer auch irrelevant - das Auto könnte seine Maximalgeschwindigkeit direkt als double speichern, über physikalische Berechnungen aus der Leistungskurve seines Motors ermitteln oder auch aus einer Datenbank des Herstellers abfragen - aber was es macht, ist Entscheidung des Autos und nicht der Maximalgeschwindigkeit)
Du widersprichst Dir grade.
Wichtig ist, dass es nach außen als Ganzes funktioniert. Ob die class VMax oder das class Car selbst die Maximalgeschwindigkeit verwaltet, ist ein Interna der Klasse Car. Es muss also kein Member sein.Eben nicht - wenn die Klasse Vmax eine Verarbeitung vorgibt, ist die Klasse car darauf angewiesen, genau diese zu nutzen.
Xin schrieb:
CStoll schrieb:
Schön, wenn du eine Sprache hast, die zwischen Zuständen und Teilobjekten unterscheiden kann. C++ kann das leider nicht, also brauchst du gar nicht versuchen, es dazu zu bringen.
Super Einstellung. "Ich" kann das nicht, also brauchst "Du" es nicht zu versuchen.
Ich versuche es trotzdem. Sich derart dagegen zu wehren bringt aber nix, ich zwinge schließlich niemanden hier, es zu nutzen.Doch, du versuchst krampfhaft, mir zu erklären, daß dein Ansatz besser ist.
Xin schrieb:
CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Wenn du einen int mit einer Maßeinheit versehen willst, um Strecken und Gewichte unterscheiden zu können, geht das in die richtige Richtung. Aber Hilfsklassen anlegen zu müssen, nur um einer Area zwei Maßzahlen übergeben zu können halte ich ein wenig übertrieben.
Ähh... moment... Du beklagst Dich, über die bei mir fehlende Unterscheidung WindowFlag und WindowFlags und jetzt wird's übertrieben, wenn ich Maßeinheiten klassifiziere?!
Ein Unterschied zwischen Zahl und Zahl mit Maßeinheit ist klar, aber den kannst du nicht vernünftig mit Vererbung nachbauen (wenn alle Maßgrößen von int abgeleitet werden, kannst du auch alle Maßgrößen als nackte int's behandeln
Kilo AddiereGewichte( Kilo a, Kilo b ) { return a+b; }
Dann übergib da mal ein int.Das ist ja auch kein Beispiel, wo es nötig ist zu vererben (btw, wenn das ohne einen eigenen op+ compiliert UND int-Übergabe verhindert, denke ich vielleicht näher über den tieferen Sinn nach).
Xin schrieb:
CStoll schrieb:
und damit auch beliebig miteinander verrechnen. Und erzähl mir blos nicht, daß du eine Addition von Gewicht+Länge auf dieser Basis verhindern kannst.
Warum sollte ich das verhindern?
4kg und 7m. Wenn ich die Zahl des Gewichts mit der Zahl der Länge addiere, erhalte ich 11. Ist doch eine legitime Fragestellung. Was immer man mit der Zahl anfangen will. Was ich nicht erhalte sind 11 Kilometer oder derartiges.Wenn ich ein Gewicht und eine Masse verrechnen, ist das genauso unsinnig wie der Cast eines Fensters nach bool).
Xin schrieb:
Ich kann aber zum Beispiel 7m * 8m berechnen. Daraus ergeben sich Meter2, die ich nicht auf eine Metervariable zuweisen kann.
Operatorüberladung ist das Zauberwort, freundlich kombiniert mit "explizit".Und was nützt dir die Vererbungsbeziehung, wenn du dann doch alles von Hand erledigen kannst? (btw, du kannst nichtmal zwei Gewichte addieren und ein Gewicht erhalten, ohne dir einen eigenen operator definieren zu müssen)
Xin schrieb:
CStoll schrieb:
Was ich an dem oberen Ansatz bemängle, ist zum Beispiel die Unterscheidung von PixelWidth und PixelHeight - beide Typen sind technisch gleichwertig und wurden nur eingeführt, damit Area zwei Pixelmaße in sich vereinigen kann.
Okay, das bemängelst Du mit einer technsich falschen Begründung. Sie sind eben nicht technisch gleichwertig, weil - wie der Name schon sagt - das eine ist eine Breite und das andere eine Höhe. Und wenn Du ein Schiff konstruierst und dabei Breite und Höhe gleichwertig, also austauschbar machst, dann könnte es sein, dass das Schiff recht merkwürdig aussieht.
Werte müssen klassifiziert werden - entweder durch die Disziplin des Entwicklers - oder durch Klassen, deren Zweck es ist, Werte zu klassifizieren.CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Und außerdem tendiert der Ansatz auf Dauer zu extrem langen Variablennamen (gerade wenn ich mehrere technisch ähnliche Klassen an verschiedenen Stellen des Programms verwenden will).
Mein Ansatz tendiert zu überhaupt keinen Variablennamen und vor allem tendiert er dazu "ähnliche" Klassen zu vermeiden.
OK, dann eben zu Klassennamen.
Hmm... Point, Area, BitMap, Soucetext, XMLEntity. Das sind keine lange Klassennamen.
Ja, die Grundtypen sind noch recht kurz, aber darauf aufbauende Hilfstypen nicht mehr - und ein PixelWidth hat außerhalb der Area keinen eigenständigen Nutzen, wäre also technisch redundant.
Xin schrieb:
CStoll schrieb:
Und schon hast du eine Asymmetrie in deinem Design - die Quelle ist ein Member, die Senke nicht. Und wenn du Filter mit mehreren Ausgängen hast, wird das Design unüberschaubar (entweder du splittest den Filter in zwei Teile auf, die die identischen Berechnungen duplizieren,
Überlege Dir mal kurz, was ein Filter ist. Einen Filter setzt man zum Beispiel in einen Laserstrahl, vorne kommt was rein, hinten kommt was raus. Du veränderst den Typ aber nicht. Es geht Licht rein und es kommt Licht raus.
Was Du kritisierst, ist kein Filter, sondern ein Adapter. Ergo falsche Kritik zu falschem Problem.
Das Design halte ich für optimal für einen Filter.Weiterhin duplizierst du keine Berechnungen, dafür gibt es notfalls templates, wenn Du das schon so lösen möchtest.
Nehmen wir das Beispiel mit dem Laser - dort kann ich einen Splitter draufsetzen, der zwei Strahlen (fast identische) hinten rausspuckt. Für deinen Ansatz bräuchte ich jetzt zwei Teilsplitter, die fast die selben Berechnungen durchführen - und das "fast" verhindert den Einsatz von Templates.
Xin schrieb:
CStoll schrieb:
du fügst eine Zwischenklasse "zwei Areas" als Ausgang und zwei Splitter zum Zerlegen dieser Klasse ein oder zwei Hilfsklassen "TargetArea1" und "TargetArea2", von denen der Filter abgeleitet wird.
Gut, bauen wir einen Adapter auf, der zwei TargetAreas hat, die natürlich nicht TargetArea heißen würden. Nehmen wir unser Fenster und adaptieren es auf vier Punkte, die dann ObenLinks, UntenRechts usw.. heißen würden und direkt übertragbar für andere Objekte wären.
Ist dir schonmal aufgefallen, daß die Fensterpunkte nicht unabhängig voneinander sind? Wenn ich die obere linke Ecke verschiebe, rutschen ihre Nachbarn hinterher (sonst würde das Fenster schnell ziemlich verbogen aussehen).
Xin schrieb:
CStoll schrieb:
Ein Fenster hat eine linke obere Ecke, eine rechte untere Ecke und noch viele Punkte dazwischen - um jeden von denen ansprechen zu können, brauchst du entsprechend viele Zwischenklassen, die der Klasse "Punkt" jeweils einen neuen Namen geben. Außerdem interessiert es mich als Außenstehenden nicht, ob das Fenster nun zwei Ecken, Ecke+Größe oder Mittelpunkt+Größe intern verwaltet - ich interessiere mich nur danach, bei Bedarf jede Ecke oder den Mittelpunkt ansprechen zu können.
Und? Hindere ich Dich oder die Verwendung von Klassifizierungen daran?
Versuch mal die Beziehungen der Fensterpunkte untereinander darzustellen.
Xin schrieb:
Es verhält sich wie WindowFlags. Nicht, wie ein Flag. Immernoch...
OK, wie ein "Flags" - aber es verhält sich auch nicht wie ein Flags, denn Flags auf bool umzuwandeln macht durchaus Sinn.
Xin schrieb:
CStoll schrieb:
Xin schrieb:
Die Allergien schmeiße ich mal raus, die verlieren zusehens Bezug zum Thema.
Den Bezug hast du doch selber angefangen.
Ich sagte, dass ein Nussallergiker nicht auf einer Nusspackung darauf hingewiesen werden, dass sie für Nussallergiker nicht geeignet sind. Denken als Grundvoraussetzung. Deine Allergien oder die Deiner Oma interessieren mich in dem Thread nicht.
Diese "Achtung, Nüsse"-Warnung steht ja nicht nur auf Nuss-Packungen

Xin schrieb:
CStoll schrieb:
OK, dann anders - andere Sprachen mögen eine Unterscheidung zwischen Zuständen des Objekts und Teilobjekten bieten - C++ stellt beides durch Member dar (daß das nicht die perfekte Lösung ist, sehe ich ein).
Dann sieh bitte auch ein, dass C++ beides auch durch Vererbung anbietet und dass das auch nicht immer die perfekte Lösung ist. Trotzdem geht es.
Ich habe noch keine praktische Anwendung (abgesehen von deinen Code-Beispielen) gesehen, wo (öffentliche) Vererbung die bessere Darstellung für interne Zustände wäre.
Xin schrieb:
CStoll schrieb:
Du bist anscheinend der Meinung, dort einen syntaktischen Unterschied zu benötigen - und wirfst darum Zustände mit Verwandschaftsbeziehungen in einen Topf.
...? Lies Dir den Satz nochmal durch...
OK, dann langsam - du versuchst, Teile und Zustände syntaktisch unterschiedlich zu behandeln. Ein neues Sprachmittel dafür zu erfinden wäre sicher eine Lösung, ein bestehendes Sprachmittel (das schon seine vorgegebene Bedeutung hat: Vererbung == "ist-ein") dafür zu verwenden ist die falsche Lösung.
Xin schrieb:
CStoll schrieb:
Tellerrand schrieb:
Ich frage mich also: was spricht überhaupt für die Variante der Vererbung und gegen die Variante der Komposition?
Da muß ich meinen Vorrednern Recht geben - du hast weder ein Argument geliefert, warum die Komposition ungeeignet wäre,
Das könnte zum Beispiel daran liegen, dass ich die ganze Zeit betone, dass sie nicht ungeeignet ist...
CStoll schrieb:
noch eins für die Überlegenheit deines Vererbungsansatzes.
Das wiederum könnte daran liegen, dass ich nicht von "Überlegenheit" spreche, sondern von Alternative.
Du kennst die bisherigen Vorgehensweisen - die sind etabliert und stellen (fast) ideal das dar, was benötigt wird. Und du stellst einen eigenen Ansatz vor, der (aus Sicht fast aller Anwesenden) schlechter auf das Problem passt. Ergo solltest du uns davon überzeugen, daß dein Ansatz mindestens genauso gut ist wie unserer.
Xin schrieb:
CStoll schrieb:
Auf den letzten Seiten hast du nur versucht, Argumente gegen deinen Ansatz zu entkräften (und damit dein Grundprinzip wieder verwässert).
Keine Ahnung, was Du als Verwässerung ansiehst.
Nehmen wir als Beispiel die "if(win)"-Frage: Nachdem du darauf aufmerksam gemacht wurdest, daß sowas möglich ist, hast du erst gegengerudert und op bool privat deklariert - und im nächsten Moment gesagt, daß du keinen privaten op bool hast, sondern nur einen Hinweis, daß man nicht if(win) fragen sollte (was letztlich den selben Effekt hat, aber nicht vom Compiler überprüft werden kann).
Xin schrieb:
Eigentlich habe ich auf den letzten Seiten nur versucht, Dir zu zeigen, dass es Alternativen gibt, die auch Vorteile bieten - eben die Typsicherheit.
Um Typsicherheit zu gewährleisten, brauche ich keine Vererbungsbeziehungen. Die bekomme ich mit einer eigenen (freistehenden) Flag-Klasse genausogut.
Xin schrieb:
Bloß nicht gucken, ob da vielleicht ein Vorteil drin verborgen sein könnte. Ich beschäftige mich neutral damit: Komposition gut, Vererbung - auch nicht schlecht.
Das "Komposition gut" fällt Dir überhaupt nicht auf, oder? Das ist nichts, wo Du dagegen sein könntest.
Noch striktere Klassifizierung erforderlich? Sehr gut, weil Disziplin zwangsverordnet.Wenn das deine Meinung ist, hast du sie bisher sehr gut versteckt - für mich sah das eher nach "Komposition brauchbar - Vererbung wesentlich besser".
Xin schrieb:
Ich führe hier keinen Wettstreit gut gegen böse. Es geht hier um eine Alternative. Gut gegen genauso gut. Vielleicht gut gegen nicht ganz so gut in C++. Vielleicht auch gut gegen etwas besser, wenn man sich damit auseinandersetzt. Ich habe damit nur begrenzte Erfahrung, ich leite nicht grundsätzlich ab. Ich leite nur ein Objekt von seinen Flags ab und überlege, ob ich neue Klassen aus Vorhandenen sinnvoll zusammenvererben kann. Was mir nicht sinnvoll erscheint, kommt als Member rein.
Die Ableitung von Flags mag vielleicht technisch möglich sein, aber sie widerspricht immer noch den OOP-Prinzipien (aber wenn du nicht objektorientiert arbeitest, ist das natürlich kein Problem). Die Definition von Hilfsklassen, nur um mehrere gleichartige Eigenschaften in ein Objekt zu packen, halte ich für unsinnig und fehleranfällig. Und du hast immer noch nicht klargestellt, was der entscheidende Vorteil davon ist - von kryptischeren Quelltexten mal abgesehen.
-
Der unterhaltungswert ist gleich null, weil ihr immer viel zu viel schreibt. das will keiner lesen