Methoden mit bool-Parametern und "Lesbarkeit" im Kontext
-
car+=10;
oder
win += rect;
Das ist doch mal eindeutig was es macht
Ich habe lange Zeit nicht verstanden warum Leute gegen Operatoren-Überladung sein können - nun weiß ich es...
-
Badestrand schrieb:
Oh, right, danke! Aber nebenbei: Hattet ihr (du und CStoll) nicht erst eine Riesen-Diskussion in einem anderen OOP-Thread? Immer diese ellenlangen Quote-Orgien, ihr kommt doch sowieso auf keinen Nenner
CStoll war an der Diskussion eigentlich nicht in der Form beteiligt. Auf einen Nenner sind kam man in der anderen Diskussion aber auch nicht.
Andererseits - wozu ist so ein Forum da? Man diskutiert mit anderen über Lösungen von Programmierproblemen und das tun CStoll und ich hier.CStoll schrieb:
Wir sind immer noch bei der alten Frage: Setze ich mit "wnd=Window::Modal;" nun das Fullscreen-Flag zurück oder nicht?
Hatte ich das nicht schon mehrfach als No-Go-Befehl geoutet, den ich für Dich extra als private setzte?
Ergo setzt wnd=Winodw::Modal den Compiler zurück und der dankt es mit einer Fehlermeldung.CStoll schrieb:
Der Punkt ist ziemlich klein im Vergleich zu einem Fenster - also welchen Wert erhalte ich, wenn ich ein Fenster als Punkt betrachte? die linke obere Ecke? die rechte untere Ecke? den Mittelpunkt? ...?
(selbst wenn wir nur von Punkt->Rechteck ausgehen, gibt es mehr als genug Möglichkeiten zu sagen, was "meine" Position sein soll)Sorry, aber das wird hier lächerlich. Jedes OS muss die Konvention machen, dass eine Punkt die Position eines Fensters angibt. Bei allem, was ich bisher dazwischen hatte, ist das der Punkt, an dem das Fenster liegt/beginnt. Ausgehend vom Koordinatensystem, das Oben-Links beginnt war das bisher immer der linke obere Punkt.
CStoll schrieb:
Xin schrieb:
Erstens sagt Dir das der Menschenverstand. Wenn Du ein Fenster um eine Distance verschiebst - und nichts anderes ist eine Addition, wenn Du Dir den Zahlenstrahl in der Grundschule in Erinnerung rufst - dass sich das Fenster dann verschiebt.
Wenn Du das nicht intuitiv findest, hilft in der Regel ein Blick in die Klassenhirachie.Ja, ich muß wieder nachsehen - und das notfalls über mehrere Dateien hinweg, bis ich den richtigen op+= für meinen Zweck finde.
Ich weiß nicht, wie Du das machst, wenn Du mit einem Framework arbeitest. Macht es plopp und Du weißt, wie die Frameworks arbeiten? Ich muss da am Anfang immer mal in die Dokumentation sehen, um mich einzuarbeiten. Sobald das geschehen ist, brauche ich nicht mehr nachzuschlagen.
Das ganze wird wirklich lächerlich. Du bringst hier Punkte an, die für Membervariablen, genauso wie für Vererbung gelten und behauptest, es wäre ein Problem bei Vererbung. Du musst Deine Variable Private erklären, ich meinen operator, um einer Frage vorzubeugen, für die der Entwickler gesteinigt gehört. Und dass man, wenn man keine Ahnung hat, auch mal in die Doku gucken muss, gefällt Dir auch nicht.Sorry, Du kannst auch gerne in die Kerbe "Xin ignoriert Argumente" hauen, wenn Du nur recht haben möchtest, aber ich sehe hier keine Argumente. Was ich sehe ist, dass ich bereit bin Dinge anders zu machen, als üblich und die Bereitschaft sich in die Richtung mit dem Thema zu beschäftigen sagen wir zurückhaltend ist.
CStoll schrieb:
Xin schrieb:
Ich würde ein Auto allerdings von Eigenschaften ableiten, die ich mehrfach verwende. Sprachlich sind wir da genauso flexibel, wie in der Programmierung.
Ein (einfarbiges) Auto kann eine Farbe sein: "Die Farbe ist rot" => "Das Auto ist rot."
Und natürlich kann ein Auto auch eine Farbe haben: "Die Farbe hat den Wert rot" => "Eine Komponente des Autos ist die rote Farbe."Ja, die Sprache kann manchmal recht mehrdeutig sein - und niemanden stört's
Aber aus OOP-Sicht ist die Vererbung von Farbe->Auto trotzdem Käse. (und um ein Auto an eine farbverarbeitende Funktion zu übergeben, ist eine Typumwandlung über 'operator Farbe()' besser geeignet).
Behauptung. Begründung?
CStoll schrieb:
Xin schrieb:
Für Leistung und aktuelle Geschwindigkeit sind bei mir keine Klassen vorhanden. Ich wüßte derzeit auch keinen Grund, derartige Klassen zur Wiederverwertung abstrahieren. Das wären bei mir vermutlich Member.
Grundsätzlich habe ich aber kein Problem damit, bei eindeutigen Aussagen Vererbung zu nutzen.leistung = Leistung( meinAuto ); meinAuto += Geschwindigkeit( 5 ); // Beschleunigen;
Vererbung ist prinzipiell nichts anderes als Membervariablen, Membervariablen entstanden aus der strukturierten Programmierung. Ich halte das Konzept der Membervariablen für sinnvoll, oft auch für richtig, aber in vielerlei Hinsicht ebenso für überholt, denn Vererbung kann Code vereinfachen.
Vererbung ist keine verkappte Member-Beziehung - mit der Vererbung gehst du auch einen Vertrag ein, das Interface der Basisklasse konsistent umzusetzen. (und außerdem hat ein Auto zwei Geschwindigkeiten - die aktuelle und die maximale - wie willst du das per Vererbung darstellen?
class VMax.: public V {}
class VCurrent : public V {}Nebenher... was soll das eigentlich? Ich sagte gleich zu Beginn, dass ich das nicht unbedingt als Klassen beschreiben würde.
Allerdings muss ich sagen, dass je mehr Du dagegen argumentierst, desto mehr gefällt mir der Ansatz, Eigenschaften in Klassen zu kapseln.CStoll schrieb:
Xin schrieb:
Member halte ich für sinnvoll, wenn sie untergeordnete Objekte enthält.
Autos bestehen aus Sitzen, sie sind aber keine. Sie können eigenständige Eigenschaften besitzen, die in Gleichbehandlung mit dem Auto mehrdeutig sein könnten:langweiligesAuto.Sitze = Farbe( langweiligesAuto );
Farbe wäre hier in einer Vererbungsbeziehung nicht eindeutig. Ein Auto als Sitzmöglichkeit anzusehen, würde ich für akzeptabel halten. Allerdings ist "Sitzmöglichkeit" keine Eigenschaft eines Autos, die unbedingt derart hervorgehoben werden muss. Aber auch das ist subjektiv - meine Oma sieht das anders.
Wie du inzwischen bemerkt hast, nicht nur die
Du siehst ein Auto auch als Sitzgelegenheit? Was beschwerst Du Dich dann? :->
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.
CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Ja, Integers kann man ver-und-en - aber Integers verwendet man auch nicht als Basis für eigene Klassen, um diese verunden zu können.
Warum eigentlich nicht?
Grade das ist doch die Kritik derer, die das "reine OOP" in C++ suchen.Weil's keinen Sinn macht? Weil C++ keine reine OOP-Sprache ist? Such dir eine Erklärung aus.
Ob es keinen Sinn hat, wage ich zu bezweifeln. Die Frage gilt ja auch nicht nach dem Ist-Zustand von C++, sondern einem möglichen Sollte-Zustand.
Dann gib mir doch mal ein sinnvolles Beispiel, um von int ableiten zu müssen.
(und zur Not kannt du auch eine echte OOP-Sprache verwenden, wie z.B. Java (Oops- da kann man ja auch nicht von Integer ableiten
))
Ja, und weil man es in C++ nicht kann, und weil man es in Java nicht kann, ist es eine dumme Idee von einem derartigen Typ abzuleiten, hmm?
class Pixel : public int {} class PixelWidth : public Pixel {} class PixelHeight : public Pixel {} class Area : public PixelWidth, public PixelHeight class BitsPerSample : public int {} class BitmapArea : public PixelWidth, public PixelHeight, public BitPerSample {} class DigiCam : public BitMapArea {} int GetMegaPixel( Area a ) { return PixelWidth( a ) * PixelHeight( a ); } DigiCam myCam; // Fill myCam printf( "%d\n", GetMegaPixel( myCam ) );
Die Tatsache, dass sich das alles mit Membervariablen lösen lässt, bedeutet nicht, dass diese Methode schlecht wäre. Dieser Sourcecode beschreibt nichts anderes als den Zugriff auf Membervariablen.
Man sollte Vererbung nicht nur als eine "ist-ein" betrachten, sondern auch sehen, dass hier eigenständige Eigenschaften zusammengebracht werden können, die eine Klasse ausmachen.Wo ich Dir recht gebe, ist dass C++ wenig Möglichkeiten bietet exakt zwischen "ist-ein" und "verhält-sich-als" zu unterscheiden. Ein "verhält-sich-als" muss selbst implementiert werden und kann nicht von einer Eigenschaft übernommen werden.
CStoll schrieb:
Der Unterschied ist konzeptionell: Ich deklariere die Flag von vornherein privat, weil ihre Existenz und Aufbau nichts im offiziellen Interface zu suchen haben. Du mußt deinen Umwandlungsoperator privat nachträglich privat deklarieren, um unsinnige Verwendungen zu verhindern.
Shade sagte, Schreibarbeit zählt nicht. Ich sagte, dass meine Methode im Aufbau erstmal mehr als weniger Schreibarbeit ist.
So what? Ich will mit WindowFlags Window implementieren, das heißt ich muss das Zusammenspiel der Klassen organisieren, und das ist problemlos machbar.Das einzige, was für mich zählt ist, wie man mit den Klassen umgehen kann, wenn sie erstmal implementiert sind.
Notfalls packe ich Dir sämtliche Flags nochmals als private in die Windowklasse, da habe ich kein Problem mit. Mir ist wichtig, dass ich garantieren kann, dass Eigenschaften zwangsläufig immer den gleichen Namen haben. Den Namen einer Eigenschaftsklasse kann ich nicht von Klasse zu Klasse ändern, den Namen einer Membervariablen schon. Das über ein Framework immer konstant zu halten, ist eine Sache, die viel mehr Disziplin verlangt, als derartige Klassen einmalig sehr ausführlich beschreiben zu müssen.CStoll schrieb:
Und damit sind wir doch wieder bei der Rechteck-Quadrat-Problematik angekommen: Du sagst: "ein Fenster ist ein Flag", "ein Flag kann nach bool konvertiert werden" und "ein Fenster kann nicht nach bool konvertiert werden" - siehst du den Widerspruch in diesen Aussagen?
Ich sagte ein Window ist eine Erweiterung zu WindowFlags und kann zu WindowFlags konvertiert werden.
Den operator bool habe ich auf Deinen Wunsch für Deppenprogrammierer jetzt private gesetzt, weil ich zustimme, dass ein Fenster kein bool ist.
Auch wenn Du es noch 10mal wiederholst, noch privater kann ich's nicht setzen. Das Problem, welches keins sein darf, weil kein denkender Entwicker diese Frage stellen darf, ist selbst für die nicht denkenden gelöst. Darauf rumzureiten, bringt uns also nicht weiter. Es ist punktuell gelöst und muss nie wieder gelöst werden.CStoll schrieb:
Xin schrieb:
Und ganz ehrlich, es gibt eine Grenze, da sichere ich nicht mehr ab. Ich baue keinen Zaun um einen großen Gastank, nur weil auf dem Tank jemand grillen könnte.
Darwin-Awards beweist, dass derartiges gemacht wird und das es tödliche Konsequenzen haben kann.
Ich finde den Kommentar "Kann Nüsse enthalten, bei Nussallergie nicht konsumieren" auf einer Packung Erdnüsse für lächerlich.Du bist ja auch kein Allergiker.
Doch. Ich bin allergisch gegen Roggen- und Graspollen. Ich vermeide zu gewissen Zeiten Grasflächen und Rasenmäher, obwohl da kein Schild steht "Für Grasallergiker zur Pollensaison nicht geeignet.". Da muss man mich nicht drauf hinweisen. Ich binde mir kein Startrakete auf's Autodach, nur weil da kein Aufkleber "nur als Starthilfe für Jets einsetzen" draufsteht.
Es gibt denkende Menschen und es gibt Menschen, die nicht denken. Und dann gibt es noch die Evolution und beides greift ineinander. Und das ist gut so...Shade Of Mine schrieb:
car+=10;
oder
win += rect;
Das ist doch mal eindeutig was es macht
Ich habe lange Zeit nicht verstanden warum Leute gegen Operatoren-Überladung sein können - nun weiß ich es...
Derartige Überladung beschreibe ich hier nicht. Bei mir steht z.B. "car += Geschwindigkeit( 10 );". Die Gefahr besteht vorrangig mit untypisierten Daten, wie eben int, die für so ziemlich alles gebraucht werden. Addiere ich einen aussagekräftigen Datentyp, ist die Handlung genauso ersichtlich, wie der Name des Datentyps.
Ich verteufle nicht eine Möglichkeit, weil sie falsch angewendet werden kann. Ich verteufle die Leute, die Möglichkeiten unüberlegt falsch anwenden. Wer Möglichkeiten absichtlich falsch anwendet, nur um sie schlecht zu machen, der sollte sich vielleicht mal mit den guten Seiten beschäftigen.
Und nebenher: Wer gegen Operatoren-Überladung ist, muss zwangsläufig auch gegen Funktionsüberladung sein, denn nichts anderes ist die operator-Überladung.
-
Xin schrieb:
CStoll schrieb:
Wir sind immer noch bei der alten Frage: Setze ich mit "wnd=Window::Modal;" nun das Fullscreen-Flag zurück oder nicht?
Hatte ich das nicht schon mehrfach als No-Go-Befehl geoutet, den ich für Dich extra als private setzte?
Ergo setzt wnd=Winodw::Modal den Compiler zurück und der dankt es mit einer Fehlermeldung.Was denn nun - auf der einen Seite bietest du einen operator= mit der Semantik "setze alle Flags zurück und stelle dann Flag xyz ein", auf der anderen Seite erklärst du mir, daß es keinen solchen Operator gibt. Entscheide dich bitte.
Xin schrieb:
CStoll schrieb:
Der Punkt ist ziemlich klein im Vergleich zu einem Fenster - also welchen Wert erhalte ich, wenn ich ein Fenster als Punkt betrachte? die linke obere Ecke? die rechte untere Ecke? den Mittelpunkt? ...?
(selbst wenn wir nur von Punkt->Rechteck ausgehen, gibt es mehr als genug Möglichkeiten zu sagen, was "meine" Position sein soll)Sorry, aber das wird hier lächerlich. Jedes OS muss die Konvention machen, dass eine Punkt die Position eines Fensters angibt. Bei allem, was ich bisher dazwischen hatte, ist das der Punkt, an dem das Fenster liegt/beginnt. Ausgehend vom Koordinatensystem, das Oben-Links beginnt war das bisher immer der linke obere Punkt.
Aber in einem vernünftigen Design gibt der Name einer Eigenschaft an, was sie bedeutet - wenn ich einen Member "Point center;" oder "Point upperleft;" habe, kann ich daraus herleiten, wie das Fenster dazu liegt. Die Vererbungsbeziehung hat keinen Namen, also muß diese Zuordnung anders dokumentiert werden.
Xin schrieb:
CStoll schrieb:
Xin schrieb:
Ich würde ein Auto allerdings von Eigenschaften ableiten, die ich mehrfach verwende. Sprachlich sind wir da genauso flexibel, wie in der Programmierung.
Ein (einfarbiges) Auto kann eine Farbe sein: "Die Farbe ist rot" => "Das Auto ist rot."
Und natürlich kann ein Auto auch eine Farbe haben: "Die Farbe hat den Wert rot" => "Eine Komponente des Autos ist die rote Farbe."Ja, die Sprache kann manchmal recht mehrdeutig sein - und niemanden stört's
Aber aus OOP-Sicht ist die Vererbung von Farbe->Auto trotzdem Käse. (und um ein Auto an eine farbverarbeitende Funktion zu übergeben, ist eine Typumwandlung über 'operator Farbe()' besser geeignet).
Behauptung. Begründung?
Hast du schonmal versucht, dein Haus mit einem Auto zu lackieren? Wenn ja, was ist dabei herausgekommen?
Xin schrieb:
CStoll schrieb:
Xin schrieb:
Für Leistung und aktuelle Geschwindigkeit sind bei mir keine Klassen vorhanden. Ich wüßte derzeit auch keinen Grund, derartige Klassen zur Wiederverwertung abstrahieren. Das wären bei mir vermutlich Member.
Grundsätzlich habe ich aber kein Problem damit, bei eindeutigen Aussagen Vererbung zu nutzen.leistung = Leistung( meinAuto ); meinAuto += Geschwindigkeit( 5 ); // Beschleunigen;
Vererbung ist prinzipiell nichts anderes als Membervariablen, Membervariablen entstanden aus der strukturierten Programmierung. Ich halte das Konzept der Membervariablen für sinnvoll, oft auch für richtig, aber in vielerlei Hinsicht ebenso für überholt, denn Vererbung kann Code vereinfachen.
Vererbung ist keine verkappte Member-Beziehung - mit der Vererbung gehst du auch einen Vertrag ein, das Interface der Basisklasse konsistent umzusetzen. (und außerdem hat ein Auto zwei Geschwindigkeiten - die aktuelle und die maximale - wie willst du das per Vererbung darstellen?
class VMax.: public V {}
class VCurrent : public V {}Nebenher... was soll das eigentlich? Ich sagte gleich zu Beginn, dass ich das nicht unbedingt als Klassen beschreiben würde.
Allerdings muss ich sagen, dass je mehr Du dagegen argumentierst, desto mehr gefällt mir der Ansatz, Eigenschaften in Klassen zu kapseln.Wo du ständig auf Kürze rumreitest - was ist der Unterschied zwischen "c = VCurrent(v);" und "c.VCurrent = v;"? Ich finde jedenfalls letzeres klarer.
Xin schrieb:
CStoll schrieb:
Xin schrieb:
Member halte ich für sinnvoll, wenn sie untergeordnete Objekte enthält.
Autos bestehen aus Sitzen, sie sind aber keine. Sie können eigenständige Eigenschaften besitzen, die in Gleichbehandlung mit dem Auto mehrdeutig sein könnten:langweiligesAuto.Sitze = Farbe( langweiligesAuto );
Farbe wäre hier in einer Vererbungsbeziehung nicht eindeutig. Ein Auto als Sitzmöglichkeit anzusehen, würde ich für akzeptabel halten. Allerdings ist "Sitzmöglichkeit" keine Eigenschaft eines Autos, die unbedingt derart hervorgehoben werden muss. Aber auch das ist subjektiv - meine Oma sieht das anders.
Wie du inzwischen bemerkt hast, nicht nur die
Du siehst ein Auto auch als Sitzgelegenheit? Was beschwerst Du Dich dann? :->
Nein, aber ich sehe ein Auto auch nicht als Geschwindigkeit an
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")
Xin schrieb:
CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Ja, Integers kann man ver-und-en - aber Integers verwendet man auch nicht als Basis für eigene Klassen, um diese verunden zu können.
Warum eigentlich nicht?
Grade das ist doch die Kritik derer, die das "reine OOP" in C++ suchen.Weil's keinen Sinn macht? Weil C++ keine reine OOP-Sprache ist? Such dir eine Erklärung aus.
Ob es keinen Sinn hat, wage ich zu bezweifeln. Die Frage gilt ja auch nicht nach dem Ist-Zustand von C++, sondern einem möglichen Sollte-Zustand.
Dann gib mir doch mal ein sinnvolles Beispiel, um von int ableiten zu müssen.
(und zur Not kannt du auch eine echte OOP-Sprache verwenden, wie z.B. Java (Oops- da kann man ja auch nicht von Integer ableiten
))
Ja, und weil man es in C++ nicht kann, und weil man es in Java nicht kann, ist es eine dumme Idee von einem derartigen Typ abzuleiten, hmm?
class Pixel : public int {} class PixelWidth : public Pixel {} class PixelHeight : public Pixel {} class Area : public PixelWidth, public PixelHeight class BitsPerSample : public int {} class BitmapArea : public PixelWidth, public PixelHeight, public BitPerSample {} class DigiCam : public BitMapArea {} int GetMegaPixel( Area a ) { return PixelWidth( a ) * PixelHeight( a ); } DigiCam myCam; // Fill myCam printf( "%d\n", GetMegaPixel( myCam ) );
Die Tatsache, dass sich das alles mit Membervariablen lösen lässt, bedeutet nicht, dass diese Methode schlecht wäre. Dieser Sourcecode beschreibt nichts anderes als den Zugriff auf Membervariablen.
Und was hast du davon? Kiloweise Hilfsklassen, die nichts anderes machen, als 'int' einen neuen Namen zu geben. In der Anwendung ist sowas bestenfalls gewöhnungsbedürftig - und schlimmstenfalls füllst du dir den globalen Namensraum mit Bezeichnern, die nur in Zusammenwirken mit deinen Klassen eine Bedeutung haben.
Xin schrieb:
Man sollte Vererbung nicht nur als eine "ist-ein" betrachten, sondern auch sehen, dass hier eigenständige Eigenschaften zusammengebracht werden können, die eine Klasse ausmachen.
Vererbung in C++ stellt nunmal eine "ist-ein"-Beziehung dar - auch wenn du dich auf den Kopf stellst, mußt du andere Anwendungen erst einmal begründen.
Xin schrieb:
CStoll schrieb:
Der Unterschied ist konzeptionell: Ich deklariere die Flag von vornherein privat, weil ihre Existenz und Aufbau nichts im offiziellen Interface zu suchen haben. Du mußt deinen Umwandlungsoperator privat nachträglich privat deklarieren, um unsinnige Verwendungen zu verhindern.
Shade sagte, Schreibarbeit zählt nicht. Ich sagte, dass meine Methode im Aufbau erstmal mehr als weniger Schreibarbeit ist.
So what? Ich will mit WindowFlags Window implementieren, das heißt ich muss das Zusammenspiel der Klassen organisieren, und das ist problemlos machbar.Das einzige, was für mich zählt ist, wie man mit den Klassen umgehen kann, wenn sie erstmal implementiert sind.
Notfalls packe ich Dir sämtliche Flags nochmals als private in die Windowklasse, da habe ich kein Problem mit. Mir ist wichtig, dass ich garantieren kann, dass Eigenschaften zwangsläufig immer den gleichen Namen haben. Den Namen einer Eigenschaftsklasse kann ich nicht von Klasse zu Klasse ändern, den Namen einer Membervariablen schon. Das über ein Framework immer konstant zu halten, ist eine Sache, die viel mehr Disziplin verlangt, als derartige Klassen einmalig sehr ausführlich beschreiben zu müssen.Die Namen der öffentlichen Schnittstelle werden auch in der Hierarchie durchgereicht, also wo siehst du das Problem? (wie die privaten Member heißen, geht niemanden außerhalb der Klasse etwas an, also ist da auch keine Konsistenz erforderlich)
Xin schrieb:
CStoll schrieb:
Und damit sind wir doch wieder bei der Rechteck-Quadrat-Problematik angekommen: Du sagst: "ein Fenster ist ein Flag", "ein Flag kann nach bool konvertiert werden" und "ein Fenster kann nicht nach bool konvertiert werden" - siehst du den Widerspruch in diesen Aussagen?
Ich sagte ein Window ist eine Erweiterung zu WindowFlags und kann zu WindowFlags konvertiert werden.
Den operator bool habe ich auf Deinen Wunsch für Deppenprogrammierer jetzt private gesetzt, weil ich zustimme, dass ein Fenster kein bool ist.
Auch wenn Du es noch 10mal wiederholst, noch privater kann ich's nicht setzen. Das Problem, welches keins sein darf, weil kein denkender Entwicker diese Frage stellen darf, ist selbst für die nicht denkenden gelöst. Darauf rumzureiten, bringt uns also nicht weiter. Es ist punktuell gelöst und muss nie wieder gelöst werden.Ja, das Problem hast du gelöst, aber damit die "ist-ein"-Beziehung zwischen WindowFlags und Window ausgehebelt. Wenn Window ein WindowFlags ist, muß es auch alles können, was ein WindowFlags kann - ergo ist eine der drei Aussagen falsch:
- Window ist kein WindowFlags - die Vererbung passt nicht
- Window kann nach bool konvertiert werden - hattest du explizit verboten
- WindowFlags kann nicht nach bool konvertiert werden - ist auch nicht machbar, weil diese Umwandlung benötigt wird
Xin schrieb:
CStoll schrieb:
Xin schrieb:
Und ganz ehrlich, es gibt eine Grenze, da sichere ich nicht mehr ab. Ich baue keinen Zaun um einen großen Gastank, nur weil auf dem Tank jemand grillen könnte.
Darwin-Awards beweist, dass derartiges gemacht wird und das es tödliche Konsequenzen haben kann.
Ich finde den Kommentar "Kann Nüsse enthalten, bei Nussallergie nicht konsumieren" auf einer Packung Erdnüsse für lächerlich.Du bist ja auch kein Allergiker.
Doch. Ich bin allergisch gegen Roggen- und Graspollen. Ich vermeide zu gewissen Zeiten Grasflächen und Rasenmäher, obwohl da kein Schild steht "Für Grasallergiker zur Pollensaison nicht geeignet.". Da muss man mich nicht drauf hinweisen. Ich binde mir kein Startrakete auf's Autodach, nur weil da kein Aufkleber "nur als Starthilfe für Jets einsetzen" draufsteht.
Es gibt denkende Menschen und es gibt Menschen, die nicht denken. Und dann gibt es noch die Evolution und beides greift ineinander. Und das ist gut so...Ich hab' auch Heuschnupfen, meine Oma eine Allergie gegen Paprika (kein Problem, den kann man noch erkennen, bevor man ihn runterschluckt) etc. Aber irgendwo sind technische Grenzen dessen, was man noch mit gesundem Menschenverstand erkennen kann - und solange du nicht selber zugesehen hast, wie es hergestellt wurde, kannst du nicht sicher sein, ob dein Vollkornmüsli in der Nähe von Nüssen zwischengelagert wurde.
Xin schrieb:
Und nebenher: Wer gegen Operatoren-Überladung ist, muss zwangsläufig auch gegen Funktionsüberladung sein, denn nichts anderes ist die operator-Überladung.
Ja zurück zu den Wurzeln - schreiben wir wieder in C
-
CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Wir sind immer noch bei der alten Frage: Setze ich mit "wnd=Window::Modal;" nun das Fullscreen-Flag zurück oder nicht?
Hatte ich das nicht schon mehrfach als No-Go-Befehl geoutet, den ich für Dich extra als private setzte?
Ergo setzt wnd=Winodw::Modal den Compiler zurück und der dankt es mit einer Fehlermeldung.Was denn nun - auf der einen Seite bietest du einen operator= mit der Semantik "setze alle Flags zurück und stelle dann Flag xyz ein", auf der anderen Seite erklärst du mir, daß es keinen solchen Operator gibt. Entscheide dich bitte.
Für Dich gibt's keinen, weil Du das böse findest. Ich brauche nicht unbedingt einen.
CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Aber aus OOP-Sicht ist die Vererbung von Farbe->Auto trotzdem Käse. (und um ein Auto an eine farbverarbeitende Funktion zu übergeben, ist eine Typumwandlung über 'operator Farbe()' besser geeignet).
Behauptung. Begründung?
Hast du schonmal versucht, dein Haus mit einem Auto zu lackieren? Wenn ja, was ist dabei herausgekommen?
Es gibt Menschen, für die gilt:
Ferrari = Farbe( Handtaeschchen );Nichtsdestotrotz wird der Ferrari dann vom Operator nicht eingefärbt, sondern lackiert. Die Information Farbe enthält schließlich nicht die Färbungsvorschrift.
Also hat die Frage irgendwas mit dem Problem zu tun? Die Postings werden zu lang, sowas kannst Du also in Zukunft auch weglassen.CStoll schrieb:
Wo du ständig auf Kürze rumreitest - was ist der Unterschied zwischen "c = VCurrent(v);" und "c.VCurrent = v;"? Ich finde jedenfalls letzeres klarer.
Hehehe, ich habe die Lösung, die mehr mehr Schreibarbeit bedeutet und jetzt behauptest Du, ich reite ständig auf der Kürze herrum?
Die Verkürzung im Algorithmus ist ein sehr guter Vorteil, ob das den Mehraufwand rausholt, weiß ich nicht. Also wird die "Kürze" allgemein nicht der alleinige Grund sein - den Hauptgrund hast Du ja bereits gesehen.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.
Zustände kann man haben, aber auch vererben. Das ist eine Designentscheidung. Man kann einen Dialog auch mit einer "besteht-aus"-Beziehung realisieren.
Ich sehe keinen Grund, warum man einen Geschwindkeitszustand nicht erben könnte.
So könnte man zum Beispiel Physikalische Eigenschaften verbinden und Gegenstände wie Autos und Äpfel mit Masse und Geschwindigkeit, Positionen und Ausmaßen ausstatten und gucken was passiert, wenn sich Autos gegen rollende Äpfel prallen, ohne Autos oder Äpfel zu verändern.
Das geht bei Membern genausowenig, wie bei schlechten Beziehungen zwischen Klassen.CStoll schrieb:
Xin schrieb:
Die Tatsache, dass sich das alles mit Membervariablen lösen lässt, bedeutet nicht, dass diese Methode schlecht wäre. Dieser Sourcecode beschreibt nichts anderes als den Zugriff auf Membervariablen.
Und was hast du davon? Kiloweise Hilfsklassen, die nichts anderes machen, als 'int' einen neuen Namen zu geben. In der Anwendung ist sowas bestenfalls gewöhnungsbedürftig - und schlimmstenfalls füllst du dir den globalen Namensraum mit Bezeichnern, die nur in Zusammenwirken mit deinen Klassen eine Bedeutung haben.
Und die vor allem ein int genau klassifizieren. Eine Funktion, die eine Strecke erwartet, kann nicht mehr mit einer Fläche gefüttert werden. Das dafür viele Klassen erforderlich sind, schmällert den Mehrwert nicht, schließlich ist der Sinn von Klassen, Datensätze zu klassifizieren, selbst wenn sie nur aus einem int bestehen.
CStoll schrieb:
Xin schrieb:
Man sollte Vererbung nicht nur als eine "ist-ein" betrachten, sondern auch sehen, dass hier eigenständige Eigenschaften zusammengebracht werden können, die eine Klasse ausmachen.
Vererbung in C++ stellt nunmal eine "ist-ein"-Beziehung dar - auch wenn du dich auf den Kopf stellst, mußt du andere Anwendungen erst einmal begründen.
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 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?
CStoll schrieb:
Xin schrieb:
Das einzige, was für mich zählt ist, wie man mit den Klassen umgehen kann, wenn sie erstmal implementiert sind.
Notfalls packe ich Dir sämtliche Flags nochmals als private in die Windowklasse, da habe ich kein Problem mit. Mir ist wichtig, dass ich garantieren kann, dass Eigenschaften zwangsläufig immer den gleichen Namen haben. Den Namen einer Eigenschaftsklasse kann ich nicht von Klasse zu Klasse ändern, den Namen einer Membervariablen schon. Das über ein Framework immer konstant zu halten, ist eine Sache, die viel mehr Disziplin verlangt, als derartige Klassen einmalig sehr ausführlich beschreiben zu müssen.Die Namen der öffentlichen Schnittstelle werden auch in der Hierarchie durchgereicht, also wo siehst du das Problem?
Ich habe keinen Bock in die Doku zu gucken. Kenne ich die Klassen, habe ich alles, was ich brauche, um an die Daten zu kommen, die mich interessieren.
CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Und damit sind wir doch wieder bei der Rechteck-Quadrat-Problematik angekommen: Du sagst: "ein Fenster ist ein Flag", "ein Flag kann nach bool konvertiert werden" und "ein Fenster kann nicht nach bool konvertiert werden" - siehst du den Widerspruch in diesen Aussagen?
Ich sagte ein Window ist eine Erweiterung zu WindowFlags und kann zu WindowFlags konvertiert werden.
Den operator bool habe ich auf Deinen Wunsch für Deppenprogrammierer jetzt private gesetzt, weil ich zustimme, dass ein Fenster kein bool ist.
Auch wenn Du es noch 10mal wiederholst, noch privater kann ich's nicht setzen. Das Problem, welches keins sein darf, weil kein denkender Entwicker diese Frage stellen darf, ist selbst für die nicht denkenden gelöst. Darauf rumzureiten, bringt uns also nicht weiter. Es ist punktuell gelöst und muss nie wieder gelöst werden.Ja, das Problem hast du gelöst, aber damit die "ist-ein"-Beziehung zwischen WindowFlags und Window ausgehebelt. Wenn Window ein WindowFlags ist, muß es auch alles können, was ein WindowFlags kann - ergo ist eine der drei Aussagen falsch:
- Window ist kein WindowFlags - die Vererbung passt nicht
- Window kann nach bool konvertiert werden - hattest du explizit verboten
- WindowFlags kann nicht nach bool konvertiert werden - ist auch nicht machbar, weil diese Umwandlung benötigt wird
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.
Wenn ich diese Sachen verbiete, habe ich das auch kein Problem mit, denn Du sagst, dass ausschließlich die "ist-ein"-Beziehung der wahre Glaube ist. Ich frage nach dem Nutzen einer Beziehung und beschreibe die Beziehung so, dass sie mir nützt.
Ich kann also vieles, was ich geerbt habe auch Private setzen, dann ist ein Window kein WindowFlag mehr, aber das ist für die Beziehung auch nicht erforderlich.
Ich kann auch WindowFlag und WindowFlags trennen und Window nur von WindowFlags ableiten, die Operatoren global definieren und alle sind glücklich - inkl. Compiler - das ist die perfekte Lösung.
Das ist mir allerdings zu aufwendig, nur damit irgendwelche Flags nicht im Namensraum von Window auftreten und man eine Frage nicht stellen kann, die ein intelligenter Entwickler niemals stellen würde. Das bringt mir zuwenig nutzen, um es umzusetzen und darum gehe ich den einfacheren Weg, der einige Risiken von "int Flags" nicht beseitigt bei den Algorithmen allerdings den Code - subjektiv empfunden - vereinfacht und der mehr Typsicherheit bietet.CStoll schrieb:
Ich hab' auch Heuschnupfen, meine Oma eine Allergie gegen Paprika (kein Problem, den kann man noch erkennen, bevor man ihn runterschluckt) etc. Aber irgendwo sind technische Grenzen dessen, was man noch mit gesundem Menschenverstand erkennen kann - und solange du nicht selber zugesehen hast, wie es hergestellt wurde, kannst du nicht sicher sein, ob dein Vollkornmüsli in der Nähe von Nüssen zwischengelagert wurde.
Und wenn Du als Nussallergiker eine Packung Nüsse kaufst, dann hast Du Probleme zu erkennen, dass da Nüsse drin sein könnten?
Hier geht es um Dokumentationsnotwendigkeit - wieviel Verstand darf man einem Entwickler zutrauen. Ob im Detail ein Vollkornmüsli in der Nähe von Nüssen geparkt wird, spielt bei einer Designentscheidung keine Rolle, da würde man das als Designfehler bezeichnen. Hier stellt sich die Frage, ob Du als Nussallergiker darauf hingewiesen werden musst, dass Nüsse Nüsse enthalten werden können. Wer ohne Schulung nicht verstehen kann, dass er keine Nüsse verträgt und deswegen keine Nüsse essen darf, der sollte nicht entwickeln.
CStoll schrieb:
Xin schrieb:
Und nebenher: Wer gegen Operatoren-Überladung ist, muss zwangsläufig auch gegen Funktionsüberladung sein, denn nichts anderes ist die operator-Überladung.
Ja zurück zu den Wurzeln - schreiben wir wieder in C
Das war exakt mein Gedanke, als ich Shades Posting las...
-
Operatoren Überladung ist nicht gleich Funktionsüberladung da Operatoren vordefinierte Bedeutungen haben.
Ein operator+ ist zB eine Funktion addXXX() - und meine Kritik ist, dass hier Operatoren für etwas eingesetzt werden was nicht der mathematischen auffassung entspricht. Ähnlich wie << als ausgabe-operator.
Meine kritik also ist, dass ein
car+=10;
einem
car.add(10);
entspricht und das unlogisch ist. man braucht ein increaseSpeed oder sonst etwas dass auf die geschwindigkeit hinweist, da man sonst den leser des codes verwirrt.
-
Xin schrieb:
Ich finde den Kommentar "Kann Nüsse enthalten, bei Nussallergie nicht konsumieren" auf einer Packung Erdnüsse für lächerlich.
Wieder mal glaubst Du Dich im Besitz der absoluten Wahrheit. Anstatt einfach mal die Möglichkeit zu überdenken, daß Nüsse im Sinne dieses Hinweises etwas anderes sind als das, was Du Dir unter Nüssen vorstellst.
Zu Deinem restlichen Unfug braucht man schon nix mehr zu sagen. Fenster sind keine Flags, sondern haben (vielleicht) welche.
Ansonsten erklär einfach mal, was Deiner Meinung nach ein Flag ist. Ich bin an Deiner Meinung interessiert, jedoch nicht an Ablenkungsmanövern.
-
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(?)).
Xin schrieb:
CStoll schrieb:
Xin schrieb:
Die Tatsache, dass sich das alles mit Membervariablen lösen lässt, bedeutet nicht, dass diese Methode schlecht wäre. Dieser Sourcecode beschreibt nichts anderes als den Zugriff auf Membervariablen.
Und was hast du davon? Kiloweise Hilfsklassen, die nichts anderes machen, als 'int' einen neuen Namen zu geben. In der Anwendung ist sowas bestenfalls gewöhnungsbedürftig - und schlimmstenfalls füllst du dir den globalen Namensraum mit Bezeichnern, die nur in Zusammenwirken mit deinen Klassen eine Bedeutung haben.
Und die vor allem ein int genau klassifizieren. Eine Funktion, die eine Strecke erwartet, kann nicht mehr mit einer Fläche gefüttert werden. Das dafür viele Klassen erforderlich sind, schmällert den Mehrwert nicht, schließlich ist der Sinn von Klassen, Datensätze zu klassifizieren, selbst wenn sie nur aus einem int bestehen.
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. 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).
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 - oder ein Polygon (besteht aus einer variablen Anzahl an Punkten) in dein Design einbauen?
Xin schrieb:
CStoll schrieb:
Xin schrieb:
Man sollte Vererbung nicht nur als eine "ist-ein" betrachten, sondern auch sehen, dass hier eigenständige Eigenschaften zusammengebracht werden können, die eine Klasse ausmachen.
Vererbung in C++ stellt nunmal eine "ist-ein"-Beziehung dar - auch wenn du dich auf den Kopf stellst, mußt du andere Anwendungen erst einmal begründen.
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.
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: 9783827313058Xin schrieb:
CStoll schrieb:
Xin schrieb:
Das einzige, was für mich zählt ist, wie man mit den Klassen umgehen kann, wenn sie erstmal implementiert sind.
Notfalls packe ich Dir sämtliche Flags nochmals als private in die Windowklasse, da habe ich kein Problem mit. Mir ist wichtig, dass ich garantieren kann, dass Eigenschaften zwangsläufig immer den gleichen Namen haben. Den Namen einer Eigenschaftsklasse kann ich nicht von Klasse zu Klasse ändern, den Namen einer Membervariablen schon. Das über ein Framework immer konstant zu halten, ist eine Sache, die viel mehr Disziplin verlangt, als derartige Klassen einmalig sehr ausführlich beschreiben zu müssen.Die Namen der öffentlichen Schnittstelle werden auch in der Hierarchie durchgereicht, also wo siehst du das Problem?
Ich habe keinen Bock in die Doku zu gucken. Kenne ich die Klassen, habe ich alles, was ich brauche, um an die Daten zu kommen, die mich interessieren.
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)Xin schrieb:
CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Und damit sind wir doch wieder bei der Rechteck-Quadrat-Problematik angekommen: Du sagst: "ein Fenster ist ein Flag", "ein Flag kann nach bool konvertiert werden" und "ein Fenster kann nicht nach bool konvertiert werden" - siehst du den Widerspruch in diesen Aussagen?
Ich sagte ein Window ist eine Erweiterung zu WindowFlags und kann zu WindowFlags konvertiert werden.
Den operator bool habe ich auf Deinen Wunsch für Deppenprogrammierer jetzt private gesetzt, weil ich zustimme, dass ein Fenster kein bool ist.
Auch wenn Du es noch 10mal wiederholst, noch privater kann ich's nicht setzen. Das Problem, welches keins sein darf, weil kein denkender Entwicker diese Frage stellen darf, ist selbst für die nicht denkenden gelöst. Darauf rumzureiten, bringt uns also nicht weiter. Es ist punktuell gelöst und muss nie wieder gelöst werden.Ja, das Problem hast du gelöst, aber damit die "ist-ein"-Beziehung zwischen WindowFlags und Window ausgehebelt. Wenn Window ein WindowFlags ist, muß es auch alles können, was ein WindowFlags kann - ergo ist eine der drei Aussagen falsch:
- Window ist kein WindowFlags - die Vererbung passt nicht
- Window kann nach bool konvertiert werden - hattest du explizit verboten
- WindowFlags kann nicht nach bool konvertiert werden - ist auch nicht machbar, weil diese Umwandlung benötigt wird
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?Xin schrieb:
Wenn ich diese Sachen verbiete, habe ich das auch kein Problem mit, denn Du sagst, dass ausschließlich die "ist-ein"-Beziehung der wahre Glaube ist. Ich frage nach dem Nutzen einer Beziehung und beschreibe die Beziehung so, dass sie mir nützt.
Ich kann also vieles, was ich geerbt habe auch Private setzen, dann ist ein Window kein WindowFlag mehr, aber das ist für die Beziehung auch nicht erforderlich.
Ich kann auch WindowFlag und WindowFlags trennen und Window nur von WindowFlags ableiten, die Operatoren global definieren und alle sind glücklich - inkl. Compiler - das ist die perfekte Lösung.Oder du vererbst gleich privat und redefinierst die notwendigen Operatoren in der Window-Klasse.
Xin schrieb:
CStoll schrieb:
Ich hab' auch Heuschnupfen, meine Oma eine Allergie gegen Paprika (kein Problem, den kann man noch erkennen, bevor man ihn runterschluckt) etc. Aber irgendwo sind technische Grenzen dessen, was man noch mit gesundem Menschenverstand erkennen kann - und solange du nicht selber zugesehen hast, wie es hergestellt wurde, kannst du nicht sicher sein, ob dein Vollkornmüsli in der Nähe von Nüssen zwischengelagert wurde.
Und wenn Du als Nussallergiker eine Packung Nüsse kaufst, dann hast Du Probleme zu erkennen, dass da Nüsse drin sein könnten?
Hier geht es um Dokumentationsnotwendigkeit - wieviel Verstand darf man einem Entwickler zutrauen. Ob im Detail ein Vollkornmüsli in der Nähe von Nüssen geparkt wird, spielt bei einer Designentscheidung keine Rolle, da würde man das als Designfehler bezeichnen. Hier stellt sich die Frage, ob Du als Nussallergiker darauf hingewiesen werden musst, dass Nüsse Nüsse enthalten werden können. Wer ohne Schulung nicht verstehen kann, dass er keine Nüsse verträgt und deswegen keine Nüsse essen darf, der sollte nicht entwickeln.
Bei einer Packung Erdnüsse ist klar, daß sie Nüsse enthalten wird - bei einer Packung Vollkornmüsli ist nicht sicher, ob vielleicht doch Spuren von Nüssen hineingekommen sein können (und mitunter reichen diese Spuren schon aus, um lebensgefährlich zu werden). (edit: Zum Nachlesen - Allergie)
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
-
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).