Methoden mit bool-Parametern und "Lesbarkeit" im Kontext
-
Ich schlage mal einen anderen Ansatz vor.
Basisklasse Unit.
Davon dann abgeleitet:
1. Basiseinheiten: KGUnit, MeterUnit, etc als konstante Objekte, quasi ein enum.
2. Numerische Werte: NumberUnit, welche einen numerischen Datentyp innehält.
3. Operationen: MultiplUnit, usw welche aus zwei Units besteht.Der Wasseraufnahmekoeffizient wäre dann eine Zusammensetzung aus:
3 kg / (m² * (s^0.5)) => Andere Notation: (* 3 (/ kg (* (exp m 2) (exp s (/ 1 2))))) => MultiplUnit( NumberUnit(3), DivUnit( KGUnit(), MultiplUnit( ExpUnit( MeterUnit(), NumberUnit(2)), ExpUnit( SekUnit(), DivUnit( NumberUnit(1), NumberUnit(2))))))Sieht kompliziert aus, aber wenn man die Operatoren anbietet und aus z.B. NumberUnit(3) * KGUnit() einfach ein MultiplUnit(NumberUnit(3), KGUnit()) macht, dann lässt es sich wie gewohnt schreiben.
Das schöne daran ist, dass eine Ausgabefunktion rekursiv einfach durch alle Unit Objekte durchlaufen kann. Jede Unit Klasse kann so sehr schöne angepasste Ausgabe Funktionen haben, z.B. kann die Ausgabefunktion der MultiplUnit darauf reagieren, dass zwei NumberUnit Objekte direkt miteinander verrechnet werden. Ebenso kann dies bei der Eingabe über die Operatoren schon geschehen und eine Rechnung Wasseraufnahmekoeffizient * 8 führt nicht zu einer weiteren Schachtelung, sondern zu einem Ergebnis mit den gleichen Einheiten.
Problematischer wird das natürlich wenn es darum geht Terme wirklich zu berechnen und zu vereinfachen. Ist also erstmal nur eine Form der Darstellung, der Datenorganisation.
Ich lass das mal so als ganz anderen Ansatz stehen ... nur ein Gedanke, eine Idee, mehr nicht
-
CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Xin schrieb:
Das Dumme ist halt nur, dass die Informatik sich auch mit Einheiten beschäftigt, die sich durch SI Einheiten nur ganz schlecht ausdrücken lassen, mit denen man aber auch rechnen können muss: Butterbrot, Teppichboden, Krieger.
Ein "Butterbrot" ist keine Einheit, sondern eine Größe - die dazugehörige Einheit wäre "Anzahl".
*lach* Okay... Und wenn ich an die Steckdose packe durchströhmt mich 230 Stück Volts, richtig. Volt ist eine physikalische Größe und Größen werden in "Anzahl" gerechnet.
Du hattest Physik Leistungskurs und kennst nicht den Unterschied zwischen "Größe" und "Einheit"? Die Größe "Butterbrote" wird in "Stück" gemessen, die Größe "Spannung" in "Volt".
Der Unterschied zwischen "Größe" und "Einheit" ist also dass Butterbrote in Stück gemessen wird und Spannung Volt?
Aha. Verstehst Du die Bedeutung von dem, was Du da schreibst?Sorry, aber ich breche hier ab. Das ist doch absolut witzlos und beim Deinem restlichen Posting habe ich nicht viel interessanteres gelesen. Damit Du Dich nicht vollkommen ignoriert fühlst, will ich dennoch zu einem was schreiben:
CStoll schrieb:
Eine implizite Umwandlung kann dir an den unpassendsten Stellen entgegenkommen und deine komplette Rechnung kaputtmachen. Über eine explizite Umwandlung mußt du dem Compiler informieren, sonst verwendet er sie auch nicht.
Sowas ist vollkommen ohne Aussage, pures Geblubber. Ich verlange explizite int-Konstruktoren, Typsicherheit ist durch den Copy-Construktor gegeben. Also passt. Und dass man explizite Konstruktoren explizit aufrufen muss, ist wohl klar, sonst würde ich sie nicht explizit verlangen. Also was willst Du damit jetzt eigentlich ausdrücken!?
Wenn ich ehrlich bin, halte ich das für die Verkomplizierung von Blah: Wer's nur überfliegt, sieht tolle Worte und "deine Rechnung kaputtmachen". Dann muss das wohl'n Argument sein...
Dass Du mit impliziten int-Konstruktoren einfach nicht landen kannst, ist ein wichtiges - aber weggelassenes Detail, weil ich nur explizite erlaube. Ergo das ganze Geblubber einen Wert von exakt 0 hat, wenn Du Dich auf meine Klassen beziehen willst.Tellerrand schrieb:
Xin schrieb:
Die Reihenfolge kann eine Rolle spielen, wenn Du Verwandschaftsbeziehungen in operatoren herstellst, statt expliziter Umrechnungen.
Die Verwandschaftsbeziehung durch Operatoren hast du selber rausgehauen mit dem Satz:
Oder ein Meter * Meter einen Quadratmeter. Das ist ein Mehrwert und ein Mehrwert rechtfertigt eine Klasse.
Oookay... Aber dass zwischen Meter und Meter^2 eine andere Beziehung besteht als zwischen Meter und Millimetern, ist nachvollziehbar?
Tellerrand schrieb:
Aber mein Problem bezieht sich nicht nur auf die Reihenfolge und lässt sich genauso auf die Umwandlung über den Konstruktor übertragen.
Meter m = Meter( Millimeter( 1000 ) ) + Meter( 1 )
Bzw. wenn es die Umrechnung nicht gäbe, die Umrechnung selbst festlegen. In dem Fall hat er hier das Warnschild bekommen, dass er genau an der Stelle denken muss, damit er Millimeter und Meter nicht einfach addiert.
Das Warnschild erhält er durchaus, denn den expliziten Konstruktor vor Meter muss er schließlich aufrufen, damit er das Warnschild aus dem Weg bekommt und er sich damit absichtlich über die Vorstellungen des Compilers hinwegsetzt.
Tellerrand schrieb:
Meter m = Meter( Millimeter( 1000 ) / 1000 ) + Meter( 1 )
Der Programmierer muss wissen ob die Umrechnung so existiert.
Wenn nicht er... wer dann?
Ich mache mir das einfacher: Ich rechne nicht ohne Aufforderung um.Tellerrand schrieb:
Wie gesagt im schlimmsten Fall verwendet das jemand als Framework.
Hat in seinem Programm Zeilen wie:
Meter m = Meter( Millimeter( 1000 ) / 1000 ) + Meter( 1 )Millimeter(1000) / 1000 sind Millimeter(1)
Korrekt. Und wieder der explizite Konstruktor, damit das ganze kompilierbar wird und damit das Warnschild an den Entwickler, hier besonders aufmerksam zu sein.
Tellerrand schrieb:
Jetzt erweitert man das Framework um diese Umrechnung und aus der Zeile:
Meter m = Meter( Millimeter( 1000 ) / 1000 ) + Meter( 1 )
resultiert ein Ergebnis um den Faktor 1000 vergrößert.vergrößert? Statt 2m kämen 1,001m raus. Oder verstehe ich hier grade was falsch?
Aber auch hier muss erst das Framework verändert werden und wenn Du das Framework veränderst und damit andere Spielregeln einbaust, dann argumentierst damit Du nicht gegen meine Klasse.
Tellerrand schrieb:
Ok, dein Satz sagt ja aus, dass er an der Stelle ein Warnschild bekommen würde, warum und wie sieht das aus?
In beiden Fällen bekommt der Compiler zu einem Ausdruck Meter(Millimeter).
Als Meter(Integer) behandelt er es nur, wenn der Konstruktor Meter(Millimeter) nicht existiert.
Warnt der Compiler einen, wenn er Millimeter als Integer behandelt?Meter ist wohl eindeutig eine Größe, die auch als gebrochene Zahl vorkommt. Es von int abzuleiten ist also suboptimal. Das es sich um Beispielcharakter handelt und um keine Produktivlösung, ist wohl eindeutig.
Tellerrand schrieb:
Meine Kritik basiert ja hauptsächlich darauf, dass der Programmierer an einigen Stellen nicht mitbekommt ob nun ein Meter(1) als Integer behandelt wird oder nicht.
Ein Meter ist entweder ein Meter oder ein Integer. Wenn er sich nicht als Meter verhalten kann, wird er ein Integer. Konvertierungsoperatoren gibt es ausschließlich explizit. Rechnen kannst Du, was immer Du willst, aber du kannst nur zuweisen, wenn die Sache sicher ist oder vom Entwickler abgesegnet.
-
Xin schrieb:
Oookay... Aber dass zwischen Meter und Meter^2 eine andere Beziehung besteht als zwischen Meter und Millimetern, ist nachvollziehbar?
Ja, die Beziehung ist in beiden Fällen aber durch einen Operator hergestellt.
Mehr wollte ich nicht sagen, dachte eher du willst solche Ausdrücke wie Meter(3) + Millimeter(7) fördern.
Denn irgendwie geht es doch darum etwas zu schaffen was einem erlaubt mit Maßeinheiten zu rechnen
Zum Rest:
Da hast du glaub ich was falsch verstanden.
Ich schreibe folgendes:
Meter m = Meter( Millimeter( 1000 ) ) + Meter( 1 )Wenn der explizite Konstruktor Meter(Millimeter) mit der passenden Umrechnung existiert, dann kommt da als Ergebnis 2 Meter raus.
Existiert der explizite Konstruktor nicht, so wird Milimeter(1000) einfach als Integer Wert 1000 an den Konstruktor Meter(Integer) übergeben und das Ergebnis ist 1001 Meter.
Der Programmierer muss also höllisch aufpassen, welcher Konstruktor nun mit welcher Umwandlung auch funktioniert.
Und das Beispiel zielte darauf ab, dass eine Implementation wie:
Meter m = Meter(Millimeter(1000) / 1000) + Meter(1)
eine potentielle Fehlerquelle ist, da ja jemand auf die Idee kommen könnte und den expliziten Konstruktor Meter(Millimeter) inklusive Umrechnung implementiert.
Und da hast du dann Recht, es kommt ein Wert raus Meter(1,0001), der einfach viel zu klein ist.Fakt ist für mich, dass der Programmierer bei jedem Konstruktoraufruf darauf achten muss welche Umwandlung gemacht wird.
Das Beispiel von Shade of Mine hat durch asInt nunmal den Vorteil, dass der Entwickler diese Arbeit nicht hat. Wenn der Konstruktor Meter(Millimeter) nicht existiert, dann bekommt man das vom Compiler gesagt und man implementiert Meter(Millimeter.asInt())
Das bringt dann auch den Vorteil mit sich, dass eine spätere Implementation des Konstruktors Meter(Millimeter) keine Auswirkungen auf den schon vorhandenen Code hat.Aber auch hier muss erst das Framework verändert werden und wenn Du das Framework veränderst und damit andere Spielregeln einbaust, dann argumentierst damit Du nicht gegen meine Klasse.
Ich habe es nciht verändert, ich sage nur, dass Erweiterungen wie ein zusätzlicher Konstruktor, der nur Code weiter vereinfachen soll, sehr tiefe Auswirkungen haben kann.
Du kannst natürlich sagen dein Framework darf man nicht erweitern und du wirst es selber nie erweitern. Aber das ist in meinen Augen unrealistisch und ein Zeichen für ein schlechtes Framework. Es existieren ja andere Ansätze bei denen man mit solchen Erweiterungen keine Probleme hat.Was ich mich mittlerweile auch frage:
Was passiert bei einfachen Rechnungen wie Meter(3) * KG(5), welcher Typ kommt da raus. Und wenn da nur ein typloser Wert retuniert, was bringt mir das Framework?
Weil irgendwie sehe ich schon unmengen von verschiedenen TypKlassen und unmengen von unterschiedlichen Operatoren vor mir.
-
Habe da doch tatsächlich was übersehen.
Xin schrieb:
Dass Du mit impliziten int-Konstruktoren einfach nicht landen kannst, ist ein wichtiges - aber weggelassenes Detail, weil ich nur explizite erlaube.
Wie kann man nur explizite Integer Konstruktoren erlauben?
Kann man sagen ich verbiete es Konstruktor x(y) mit Subklassen von y aufzurufen?Weil das wäre ja auch die Variante um meine Argumente etwas zu entkräften.
-
Ist mal jemand so freundlich und fasst zusammen, was gerade diskutiert wird?
-
Tellerrand schrieb:
Xin schrieb:
Oookay... Aber dass zwischen Meter und Meter^2 eine andere Beziehung besteht als zwischen Meter und Millimetern, ist nachvollziehbar?
Ja, die Beziehung ist in beiden Fällen aber durch einen Operator hergestellt.
Mehr wollte ich nicht sagen, dachte eher du willst solche Ausdrücke wie Meter(3) + Millimeter(7) fördern.
Denn irgendwie geht es doch darum etwas zu schaffen was einem erlaubt mit Maßeinheiten zu rechnen
Natürlich möchte ich das Rechnen mit Maßeinheiten fördern. Aber natürlich möchte ich nicht viele Klassen für eine Einheit. Millimeter sind 1/1000 Meter, also möge man doch bitte möglichst in Metern rechnen.
Tellerrand schrieb:
Zum Rest:
Da hast du glaub ich was falsch verstanden.
Ich schreibe folgendes:
Meter m = Meter( Millimeter( 1000 ) ) + Meter( 1 )Wenn der explizite Konstruktor Meter(Millimeter) mit der passenden Umrechnung existiert, dann kommt da als Ergebnis 2 Meter raus.
Ich schreibe keine Konvertierungskonstruktoren, damit sind Millimeter und Meter unabhängige Größen.
Es wird auch keine geben. Wenn Du in Millimetern rechnen möchtest, dann rechne in Meter um.
Meter Millimeter( int i ) { return Meter( i / 1000 ); } int Meter::AsMilli() { return MeterValue * 1000; } Meter meter = Millimeter( 2000 ); printf( "als Millimetern: %d\n", meter.AsMilli() );Damit entspricht
Meter m = Millimeter( 1000 ) + Meter( 1 );dem, was Du erwartest, ohne dass es eine konkurrierende Meterklasse gibt.
Es gibt nur die Basiseinheit, das lässt man sich leicht merken.
int i = Millimeter( 1000 ) * Butterbrot( 7 );
ganz logisch 7 Unit.Tellerrand schrieb:
Existiert der explizite Konstruktor nicht, so wird Milimeter(1000) einfach als Integer Wert 1000 an den Konstruktor Meter(Integer) übergeben und das Ergebnis ist 1001 Meter.
Aufgrund der fehlenden Beziehung zwischen Millimeter und Meter ist das Ergebnis 1001. Die Einheit ist aber nicht Meter, sondern nicht festgelegt, bzw. "Unit". Eine Zuweisung auf Meter wird also abgelehnt, womit der Programmierer weiß, dass er hier überlegen muss, was er tun muss, um hier zwei kompatible Einheiten zu addieren.
Tellerrand schrieb:
Der Programmierer muss also höllisch aufpassen, welcher Konstruktor nun mit welcher Umwandlung auch funktioniert.
Und das Beispiel zielte darauf ab, dass eine Implementation wie:
Meter m = Meter(Millimeter(1000) / 1000) + Meter(1)
eine potentielle Fehlerquelle ist, da ja jemand auf die Idee kommen könnte und den expliziten Konstruktor Meter(Millimeter) inklusive Umrechnung implementiert.
Und da hast du dann Recht, es kommt ein Wert raus Meter(1,0001), der einfach viel zu klein ist.Auf die Idee hat niemand zu kommen, denn die Typverwaltung wird einmalig geschrieben.
Wenn ein funktionierendes Konstrukt durch fehlerhafte Erweiterungen zu Fehlern neigt, so ist das nicht in der Verantwortung desjenigen, der das funktionierende Konstrukt erstellt hat.
Wer mal eben so unüberlegt "erweitert", ohne das Konzept verstanden zu haben, hat's auch nicht besser verdient.
Das ist kein Problem meiner Klassen, sondern ein ganz allgemeines.Tellerrand schrieb:
Fakt ist für mich, dass der Programmierer bei jedem Konstruktoraufruf darauf achten muss welche Umwandlung gemacht wird.
Das Beispiel von Shade of Mine hat durch asInt nunmal den Vorteil, dass der Entwickler diese Arbeit nicht hat. Wenn der Konstruktor Meter(Millimeter) nicht existiert, dann bekommt man das vom Compiler gesagt und man implementiert Meter(Millimeter.asInt())Der Konstruktor Meter( varOfClassMillimeter ) existiert grundsätzlich nicht, also wird varOfClassMillimeter als Int aufgefasst. Wenn Dir das nicht explizit genug ist, ist das okay. Aber fraglich ist mein Vorgehen nicht.
Tellerrand schrieb:
Das bringt dann auch den Vorteil mit sich, dass eine spätere Implementation des Konstruktors Meter(Millimeter) keine Auswirkungen auf den schon vorhandenen Code hat.
Ich halte es für falsch und für einen Designfehler, zwei Klassen für eine Einheitenklasse zu implementieren.
Tellerrand schrieb:
Aber auch hier muss erst das Framework verändert werden und wenn Du das Framework veränderst und damit andere Spielregeln einbaust, dann argumentierst damit Du nicht gegen meine Klasse.
Ich habe es nciht verändert, ich sage nur, dass Erweiterungen wie ein zusätzlicher Konstruktor, der nur Code weiter vereinfachen soll, sehr tiefe Auswirkungen haben kann.
Eine Erweiterung, die tiefe Auswirkungen hat - und das ist hier der Fall - ist eine sehr deutliche Veränderung und in diesem Fall einfach nur falsch.
Tellerrand schrieb:
Du kannst natürlich sagen dein Framework darf man nicht erweitern und du wirst es selber nie erweitern. Aber das ist in meinen Augen unrealistisch und ein Zeichen für ein schlechtes Framework. Es existieren ja andere Ansätze bei denen man mit solchen Erweiterungen keine Probleme hat.
Ich sage, dass man das Framework überlegt erweitern kann. Konvertierungskonstruktoren sind keine überlegte Erweiterung.
Tellerrand schrieb:
Was ich mich mittlerweile auch frage:
Was passiert bei einfachen Rechnungen wie Meter(3) * KG(5), welcher Typ kommt da raus. Und wenn da nur ein typloser Wert retuniert, was bringt mir das Framework?
Weil irgendwie sehe ich schon unmengen von verschiedenen TypKlassen und unmengen von unterschiedlichen Operatoren vor mir.Wenn Du Meter*Kilogramm nicht klassifizierst, was Du in der Physik ja durch die Beschreibung "kg*m" tust, wie möchtest Du es sonst ausdrücken, dass es etwas anderes als eine typlose Größe ist? Schau Dir das Template an, dass CStoll im INet gefunden hat. Es ist aufwendig, weil die physikalische Schreibweise in C++ nunmal nicht 'nicht aufwendig' zu beschreiben ist.
Es gibt in C++ kein Verfahren, um typsicher und gleichzeitig einfach zu sein.
Daher muss man sich irgendwo auch überlegen, an welchem Punkt man aussteigen muss (nicht will). Man kann nicht alles abbilden, es wird immer Beispiele geben, die man nicht abbilden konnte.
Aber man kann den Alltag abbilden. Typsicherheit im Alltag, das wäre ein gigantischer Schritt nach vorne.
-
Tellerrand schrieb:
Habe da doch tatsächlich was übersehen.
Xin schrieb:
Dass Du mit impliziten int-Konstruktoren einfach nicht landen kannst, ist ein wichtiges - aber weggelassenes Detail, weil ich nur explizite erlaube.
Wie kann man nur explizite Integer Konstruktoren erlauben?
Kann man sagen ich verbiete es Konstruktor x(y) mit Subklassen von y aufzurufen?Weil das wäre ja auch die Variante um meine Argumente etwas zu entkräften.
Du kannst x nicht mit y oder Subklassen von y aufrufen, da es nur den Copyconstruktor gibt, der x oder Subklassen von x akzeptiert und den expliziten int Konstruktor.
-
Xin schrieb:
int i = Millimeter( 1000 ) * Butterbrot( 7 );
ganz logisch 7 Unit.Millimeter() ist 'ne funktion die durch 1000 teilt und Butterbrot() eine, die den originalwert wieder zurückgibt, oder wie soll man sowas verstehen?
falls das konstruktoren sind - wo sind die objekte geblieben? hat diese sprache sowas wie 'nen GC?
-
Xin schrieb:
int i = Millimeter( 1000 ) * Butterbrot( 7 );
ganz logisch 7 Unit.und wenn ich aber lieber in cgs rechne?

-
Undertaker schrieb:
falls das konstruktoren sind - wo sind die objekte geblieben? hat diese sprache sowas wie 'nen GC?

Dafür gibt es in C++ eindeutige Regeln. Das ist hier kein Problem.
-
Xin schrieb:
Tellerrand schrieb:
Wenn der explizite Konstruktor Meter(Millimeter) mit der passenden Umrechnung existiert, dann kommt da als Ergebnis 2 Meter raus.
Ich schreibe keine Konvertierungskonstruktoren, damit sind Millimeter und Meter unabhängige Größen.
Dann bringe das bitte nicht als Beispiel für andere Argumente.
Xin schrieb:
Meter m = Meter( Millimeter( 1000 ) ) + Meter( 1 );
1000 Millimeter sind 1m und damit ergibt sich 2m = 1m + 1m, die typsicher zugewiesen werden können.
Xin schrieb:
Tellerrand schrieb:
Existiert der explizite Konstruktor nicht, so wird Milimeter(1000) einfach als Integer Wert 1000 an den Konstruktor Meter(Integer) übergeben und das Ergebnis ist 1001 Meter.
Aufgrund der fehlenden Beziehung zwischen Millimeter und Meter ist das Ergebnis 1001. Die Einheit ist aber nicht Meter, sondern nicht festgelegt, bzw. "Unit". Eine Zuweisung auf Meter wird also abgelehnt, womit der Programmierer weiß, dass er hier überlegen muss, was er tun muss, um hier zwei kompatible Einheiten zu addieren.
Unit ist doch von Integer abgeleitet, wieso sollte der Konstruktor nicht mit Integer funktionieren?
Darauf läuft mein Beispiel hinaus, wie kann man einem Konstruktor Meter(Integer) verbieten, dass er mit Subklassen von Integer funktioniert.
Dass habe ich auch unten mit x(y) gefragt.Xin schrieb:
Tellerrand schrieb:
Das bringt dann auch den Vorteil mit sich, dass eine spätere Implementation des Konstruktors Meter(Millimeter) keine Auswirkungen auf den schon vorhandenen Code hat.
Ich halte es für falsch und für einen Designfehler, zwei Klassen für eine Einheitenklasse zu implementieren.
Ich halte das für OK, warum nicht? Weil dein Framework damit nicht klarkommt?
Xin schrieb:
Tellerrand schrieb:
Aber auch hier muss erst das Framework verändert werden und wenn Du das Framework veränderst und damit andere Spielregeln einbaust, dann argumentierst damit Du nicht gegen meine Klasse.
Ich habe es nciht verändert, ich sage nur, dass Erweiterungen wie ein zusätzlicher Konstruktor, der nur Code weiter vereinfachen soll, sehr tiefe Auswirkungen haben kann.
Eine Erweiterung, die tiefe Auswirkungen hat - und das ist hier der Fall - ist eine sehr deutliche Veränderung und in diesem Fall einfach nur falsch.
Es liegt nur am Design das diese kleine Erweiterung so tiefe Auswirkungen hat.
Ein Design bei dem diese kleine Erweiterungen nicht so tiefe Auswirkungen hat halte ich für besser, wenn es nur an so einer Kleinigkeit wie der Ableitung aller Klassen von Integer liegt.
Ergo ziehe ich das Design von Shade of Mine oder anderen vor.
Dein Design bietet anscheinend sehr viele Fallstricke und Regeln, aber kaum Vorteile.Xin schrieb:
Tellerrand schrieb:
Du kannst natürlich sagen dein Framework darf man nicht erweitern und du wirst es selber nie erweitern. Aber das ist in meinen Augen unrealistisch und ein Zeichen für ein schlechtes Framework. Es existieren ja andere Ansätze bei denen man mit solchen Erweiterungen keine Probleme hat.
Ich sage, dass man das Framework überlegt erweitern kann. Konvertierungskonstruktoren sind keine überlegte Erweiterung.
Dann landen wir wieder bei den Operatoren.
Mit irgendetwas musst du konvertieren, ansonsten beantworte mir nochmals folgende Frage:
Was nutzt das ganze Framework?
Die erste Antwort waren die Konvertierungsoperatoren. Da ich dort Probleme sah hast du auf Konvertierung mittels Konstruktoren verwiesen. Jetzt existieren da auch Probleme und du nimmst sie wieder raus?
Womit konvertierst du dann Maßeinheiten untereinander?In beiden Fällen habe ich übrigens die gleiche Kritik wie CStoll gebracht.
Die impliziten Typumwandlungen nach Integer machen es für den Entwickler unübersehbar welche der überschriebenen Operatoren oder überladenen Konstruktoren benutzt werden. (Deshalb nennt man es ja implizit)
Das fällt natürlich erst dann auf, wenn man Umwandlungen durchführt, welche nicht mit den reinen Werten funktionieren, also bei Meter(3) * Meter(3) ist das numerische Ergebnis dem numerischen Wert der Quadratmeter gleich.
Bei solchen Umwandlungen macht die implizite Verwendung von Integer natürlich kein Problem.Xin schrieb:
Tellerrand schrieb:
Was ich mich mittlerweile auch frage:
Was passiert bei einfachen Rechnungen wie Meter(3) * KG(5), welcher Typ kommt da raus. Und wenn da nur ein typloser Wert retuniert, was bringt mir das Framework?
Weil irgendwie sehe ich schon unmengen von verschiedenen TypKlassen und unmengen von unterschiedlichen Operatoren vor mir.Wenn Du Meter*Kilogramm nicht klassifizierst, was Du in der Physik ja durch die Beschreibung "kg*m" tust, wie möchtest Du es sonst ausdrücken, dass es etwas anderes als eine typlose Größe ist? Schau Dir das Template an, dass CStoll im INet gefunden hat. Es ist aufwendig, weil die physikalische Schreibweise in C++ nunmal nicht 'nicht aufwendig' zu beschreiben ist.
Es gibt in C++ kein Verfahren, um typsicher und gleichzeitig einfach zu sein.
Daher muss man sich irgendwo auch überlegen, an welchem Punkt man aussteigen muss (nicht will). Man kann nicht alles abbilden, es wird immer Beispiele geben, die man nicht abbilden konnte.
Aber man kann den Alltag abbilden. Typsicherheit im Alltag, das wäre ein gigantischer Schritt nach vorne.Also doch Konvertierung mittels Operatoren, dann ein paar Posts zurück und wir sind wieder bei der Verwandschaftsbeziehung mittels Operatoren.
Siehe meine Kritik an der Stelle.
Auch dort war es, der Entwickler hat keine Möglichkeit zu erkennen wann ... bla, bla... irgendwie drehen wir uns im Kreis und ich glaube langsam das hat hier keinen Sinn.
Nunja, damit steige ich dann wahrscheinlich aus.
-
Xin schrieb:
Das ist irgendwo witzlos, findest Du nicht?
Auf einmal kommt da irgendwo ein impliziter Konstruktor vom Himmel gefallen, oder wie darf ich mir das vorstellen?Du willst mir doch nicht damit argumentieren, dass wenn etwas falsch programmiert ist, falsche Ergebnisse entstehen!? Wow. Wie gut, dass das ein Problem ist, dass ausschließlich auf die Entwicklung meiner Klassen zutrifft.
Das hat nichts mit falsch zu tun. Viele meiner CTors sind nicht explizit - weil es oft sinnvoll ist so eine Umwandlung zu haben.
Du scheinst sehr viel anders zu programmieren als die meisten Leute. Aber indem du non-explicit CTors verbietest - hast du schon wieder eine Restriktion mehr die man sehr leicht übersehen kann und die viele Leute auch nicht einsehen werden.
Man darf keinen non-explicit CTors verwenden weil sonst die Typsicherheit weg ist - das klingt in meinen Augen ziemlich verrückt. Wenn ich eine Klasse Gewicht oder ähnliches schreibe, dann würde ich ihr vermutlich einen non-explicit CTor für int geben.
Xin schrieb:
Natürlich möchte ich das Rechnen mit Maßeinheiten fördern. Aber natürlich möchte ich nicht viele Klassen für eine Einheit. Millimeter sind 1/1000 Meter, also möge man doch bitte möglichst in Metern rechnen.
Das Problem aber ist: was wenn ich eine Klasse Millimeter will? Weil ich halt im Millimeter bereich rechne. Es spricht absolut nichts dagegen eine Millimeter Klassen einzuführen. Und sobald ich es einmal mache - habe ich wieder massig Probleme wo es nie einen Compilerfehler gibt.
Es gibt in C++ kein Verfahren, um typsicher und gleichzeitig einfach zu sein.
Daher muss man sich irgendwo auch überlegen, an welchem Punkt man aussteigen muss (nicht will). Man kann nicht alles abbilden, es wird immer Beispiele geben, die man nicht abbilden konnte.
Aber man kann den Alltag abbilden. Typsicherheit im Alltag, das wäre ein gigantischer Schritt nach vorne.Und genau da kommt der pragmatische Ansatz rein. Man nimmt einfach komplette Typsicherheit und erlaubt alle Operationen die man als nicht wichtig einstuft über typunsichere Methoden.
Wenn wir eine Klasse Meter machen die keine Konvertierung nach int erlaubt und eine Klasse Millimeter die es ebenfalls nicht erlaubt, sind die Typsicherheitsprobleme erledigt.
Ich kann
Meter m = Millimeter(1000);vielleicht nicht schreiben, aber ich erkenne sofort dass bei
Meter m = Millimeter(1000).asInt();ein Fehler sein kann.
Wenn ich nun
Meter m = Millimeter(1000).asInt() /1000;schreibe kann ich jederzeit Problemlos einen CTor für Meter schreiben der Millimeter nimmt ohne dass es das Verhalten ändert.
Bei deinem Ansatz wäre das nicht möglich. Dann könnte ich
Meter m = Millimeter(1000) / 1000;schreiben und es kommt das falsche raus sobald Meter einen CTor für Millimeter bekommt. Es sei denn der operator/ liefert einen Integer - dann kommt das richtig raus.
Dann hast du aber das Problem:
void foo(Millimeter m) { } Millimeter m=...; foo(m/10);Ich sehe einfach keinen Nachteil in der herkömmlichen Methode. Sie denkt einfach an alles.
PS:
statt dem asInt() hat mich MrN auf eine andere vermutlich elegantere Lösung gebracht die alle Einheiten Probleme komplett löst:int meter = (Millimeter(1000)/Millimeter(1)) / 1000;Da 1000mm / 1mm auf 1000/1 == 1000 rausläuft.
Dieser Ansatz ist mit der herkömmlichen Methode super leicht zu implementieren - denn Meter hat ja einen non-explicit CTor für int.
Bei Xins Ansatz ist sowas nur häßlich implementierbar - da Meter ja keinen non-explict CTor für int hat, muss man ihn jedesmal explizit aufrufen wenn man die Einheit weggerechnet hat...
Somit erlaubt dieser Ansatz problemlos mit allen Einheiten zu rechnen - die Einheiten die Fehlen kann man Problemlos dazu schreiben ohne auf eine besonderheit achten zu müssen. Denn wenn man vergisst dass Millimeter/Millimeter == int ist, dann beschwert sich der Compiler...
-
Ich habe mir Tellerrands und Shades Postings grade durchgelesen und wieder einiges gefunden und ich stimme Tellerand zu. Würde ich das nun wieder auseinander klamüsern und darauf antworten, drehen wir uns nur weiter im Kreis. Das kostet mir zuviel Zeit.
Shade schrieb:
Du scheinst sehr viel anders zu programmieren als die meisten Leute. Aber indem du non-explicit CTors verbietest - hast du schon wieder eine Restriktion mehr die man sehr leicht übersehen kann und die viele Leute auch nicht einsehen werden.
Ich programmiere nicht viel anders, als alle anderen auch. Sicherlich hier und da etwas anders, aber alles in allem sind bisher keine Klagen gekommen. Der Eindruck kommt sicherlich auf, weil ich hier auch Positionen beziehe, die nicht falsch, aber vollkommen unbesetzt sind. Daraus wurde schon geschlussfolgert, dass ich im Alltag keine Membervariablen benutze und was sonst noch alles für Vorstellungen in diversen Threads geäußert wurden.
Ich sage, dass die Einheiten nur auf explizite Aufforderung konvertiert werden dürfen. Das bedeutet aber nicht, dass ich irgendwem vorschreibe, wie er seine Konstruktoren zu schreiben hat.
Wer solche von mir geschriebenen Klassen von mir nutzt, bekommt explizite Konstruktoren geliefert und muss die nicht noch schreiben - er muss damit leben. Die expliziten Konstruktoren sind bei meinen Einheits-Klassen, die ich im Einsatz habe erforderlich, um dem Compiler zu selbstständiges Handeln zu verbieten, um Seiteneffekten vorzubeugen. Das ist keine Schwäche des Frameworks, sondern das Framework benutzt genau das in C++ vorhandene Schlüsselwort, um eben keine Schwachstelle zu bieten.Es funktioniert gut.
Dass ihr es nicht mögt, habt ihr zum Ausdruck gebracht. Also benutzt ihr es nicht.
Kein Problem, schreibt ihr euch halt etwas anderes.Und das würde ich auch als Fazit sehen: Jeder schreibt, was er für seine Anforderungen als optimal schreibt. Wir haben unterschiedliche Anforderungen und wir haben unterschiedliche Klassen geschrieben, um Einheiten zu beschreiben und typsicher zu verwenden.
Jeder benutzt, was er geschrieben hat und wir werden alle glücklich. Belassen wir's dabei, sonst verschwenden wir hier noch mehr Zeit, nur um uns weiter im Kreis zu drehen.
-
Xin schrieb:
Ich sage, dass die Einheiten nur auf explizite Aufforderung konvertiert werden dürfen. Das bedeutet aber nicht, dass ich irgendwem vorschreibe, wie er seine Konstruktoren zu schreiben hat.
Doch, genau das bedeutet es. Man kann deine Klassen nicht verwenden ohne Typsicherheit zu verlieren wenn man non-explizite CTors hat.
-
Xin schrieb:
CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Xin schrieb:
Das Dumme ist halt nur, dass die Informatik sich auch mit Einheiten beschäftigt, die sich durch SI Einheiten nur ganz schlecht ausdrücken lassen, mit denen man aber auch rechnen können muss: Butterbrot, Teppichboden, Krieger.
Ein "Butterbrot" ist keine Einheit, sondern eine Größe - die dazugehörige Einheit wäre "Anzahl".
*lach* Okay... Und wenn ich an die Steckdose packe durchströhmt mich 230 Stück Volts, richtig. Volt ist eine physikalische Größe und Größen werden in "Anzahl" gerechnet.
Du hattest Physik Leistungskurs und kennst nicht den Unterschied zwischen "Größe" und "Einheit"? Die Größe "Butterbrote" wird in "Stück" gemessen, die Größe "Spannung" in "Volt".
Der Unterschied zwischen "Größe" und "Einheit" ist also dass Butterbrote in Stück gemessen wird und Spannung Volt?
Aha. Verstehst Du die Bedeutung von dem, was Du da schreibst?Du begreifst's nicht, oder wie? "Butterbrote" ist eine Größe und wird in "Stück" gemessen, "Spannung" ist auch eine Größe und wird in "Volt" gemessen.
Xin schrieb:
CStoll schrieb:
Eine implizite Umwandlung kann dir an den unpassendsten Stellen entgegenkommen und deine komplette Rechnung kaputtmachen. Über eine explizite Umwandlung mußt du dem Compiler informieren, sonst verwendet er sie auch nicht.
Sowas ist vollkommen ohne Aussage, pures Geblubber. Ich verlange explizite int-Konstruktoren, Typsicherheit ist durch den Copy-Construktor gegeben. Also passt. Und dass man explizite Konstruktoren explizit aufrufen muss, ist wohl klar, sonst würde ich sie nicht explizit verlangen. Also was willst Du damit jetzt eigentlich ausdrücken!?
Wenn ich ehrlich bin, halte ich das für die Verkomplizierung von Blah: Wer's nur überfliegt, sieht tolle Worte und "deine Rechnung kaputtmachen". Dann muss das wohl'n Argument sein...
Dass Du mit impliziten int-Konstruktoren einfach nicht landen kannst, ist ein wichtiges - aber weggelassenes Detail, weil ich nur explizite erlaube. Ergo das ganze Geblubber einen Wert von exakt 0 hat, wenn Du Dich auf meine Klassen beziehen willst.Du hast keine implizite Umwandlung von int in irgendeine physikalische Größe - aber du hast sehr wohl eine implizite Umwandlung von physikalischen Größen nach int (die würde dir C++ schon durch/wegen der Ableitung zur Verfügung stellen).
Xin schrieb:
Tellerrand schrieb:
Xin schrieb:
Die Reihenfolge kann eine Rolle spielen, wenn Du Verwandschaftsbeziehungen in operatoren herstellst, statt expliziter Umrechnungen.
Die Verwandschaftsbeziehung durch Operatoren hast du selber rausgehauen mit dem Satz:
Oder ein Meter * Meter einen Quadratmeter. Das ist ein Mehrwert und ein Mehrwert rechtfertigt eine Klasse.
Oookay... Aber dass zwischen Meter und Meter^2 eine andere Beziehung besteht als zwischen Meter und Millimetern, ist nachvollziehbar?
Flächen (m²) und Längen (m) sind etwas völlig unterschiedliches, Längen (m) und Längen (mm) unterscheiden sich nur in der Größenordnung.
Xin schrieb:
Tellerrand schrieb:
Aber mein Problem bezieht sich nicht nur auf die Reihenfolge und lässt sich genauso auf die Umwandlung über den Konstruktor übertragen.
Meter m = Meter( Millimeter( 1000 ) ) + Meter( 1 )
Bzw. wenn es die Umrechnung nicht gäbe, die Umrechnung selbst festlegen. In dem Fall hat er hier das Warnschild bekommen, dass er genau an der Stelle denken muss, damit er Millimeter und Meter nicht einfach addiert.
Das Warnschild erhält er durchaus, denn den expliziten Konstruktor vor Meter muss er schließlich aufrufen, damit er das Warnschild aus dem Weg bekommt und er sich damit absichtlich über die Vorstellungen des Compilers hinwegsetzt.
Tellerrand schrieb:
Meter m = Meter( Millimeter( 1000 ) / 1000 ) + Meter( 1 )
Der Programmierer muss wissen ob die Umrechnung so existiert.
Wenn nicht er... wer dann?
Ich mache mir das einfacher: Ich rechne nicht ohne Aufforderung um.Du hast selber zwei Möglichkeiten genannt, Meter und Millimeter ineinander umzuwandeln - beide sind syntaktisch korrekt. Allerdings mußt du als Bibliotheksentwickler dokumentieren, welche Möglichkeit semantisch korrekt ist. Das heißt, wenn du nach längerer Überzeugungsarbeit der Anwender tatsächlich eingesehen hast, eine Umrechnung von Millimetern nach Metern zur Verfügung zu stellen, müssten alle Stellen, wo das bisher von Hand erledigt wurde, geändert werden - und kein mir bekannter Compiler wird dich darauf hinweisen, daß die manuelle Umrechnung semantisch nicht mehr nötig ist.
Xin schrieb:
Tellerrand schrieb:
Ok, dein Satz sagt ja aus, dass er an der Stelle ein Warnschild bekommen würde, warum und wie sieht das aus?
In beiden Fällen bekommt der Compiler zu einem Ausdruck Meter(Millimeter).
Als Meter(Integer) behandelt er es nur, wenn der Konstruktor Meter(Millimeter) nicht existiert.
Warnt der Compiler einen, wenn er Millimeter als Integer behandelt?Meter ist wohl eindeutig eine Größe, die auch als gebrochene Zahl vorkommt. Es von int abzuleiten ist also suboptimal. Das es sich um Beispielcharakter handelt und um keine Produktivlösung, ist wohl eindeutig.
Und wieso verkaufst du uns dann deinen Ansatz bisher als Produktivlösung?
Xin schrieb:
Tellerrand schrieb:
Meine Kritik basiert ja hauptsächlich darauf, dass der Programmierer an einigen Stellen nicht mitbekommt ob nun ein Meter(1) als Integer behandelt wird oder nicht.
Ein Meter ist entweder ein Meter oder ein Integer. Wenn er sich nicht als Meter verhalten kann, wird er ein Integer. Konvertierungsoperatoren gibt es ausschließlich explizit. Rechnen kannst Du, was immer Du willst, aber du kannst nur zuweisen, wenn die Sache sicher ist oder vom Entwickler abgesegnet.
Und woher weißt du als Bibliotheksentwickler, was für den Anwender sinnvoll ist?
Kommen wir mal zurück zur Addition "1 Schraubenschüssel + 1 Werkzeugkasten":
- der Handwerker will wissen, wieviele Werkzeuge er insgesamt hat
- ein Spediteur interessiert sich für das Gewicht
- ein Händler benötigt den Preis
- ...
- ich als Programmierer sehe nur die Objekte als digitale Repräsentation - und weiß überhaupt nichts über die erwartete Semantik der Addition
Meine Antwort darauf lautet "Ich weiß nicht, was ich hier addieren soll - also erkläre es mir bitte", du sagst "Ich weiß zwar nicht, was ich hier mache, aber hier hast du ein Ergebnis, das möglicherweise sinnvoll ist".
Xin schrieb:
Tellerrand schrieb:
Xin schrieb:
Oookay... Aber dass zwischen Meter und Meter^2 eine andere Beziehung besteht als zwischen Meter und Millimetern, ist nachvollziehbar?
Ja, die Beziehung ist in beiden Fällen aber durch einen Operator hergestellt.
Mehr wollte ich nicht sagen, dachte eher du willst solche Ausdrücke wie Meter(3) + Millimeter(7) fördern.
Denn irgendwie geht es doch darum etwas zu schaffen was einem erlaubt mit Maßeinheiten zu rechnen
Natürlich möchte ich das Rechnen mit Maßeinheiten fördern. Aber natürlich möchte ich nicht viele Klassen für eine Einheit. Millimeter sind 1/1000 Meter, also möge man doch bitte möglichst in Metern rechnen.
Du brauchst auch nicht für jede Einheit eine eigene Klasse, sondern für jede Größe - das heißt es gibt eine Klasse "Laenge" (die intern den Wert in Metern speichert) und Hilfsfunktionen Meter(), Millimeter(), Kilometer() etc, die alle ihren Parameter passend skalieren und in ein Laenge-Objekt packen.
Xin schrieb:
Tellerrand schrieb:
Zum Rest:
Da hast du glaub ich was falsch verstanden.
Ich schreibe folgendes:
Meter m = Meter( Millimeter( 1000 ) ) + Meter( 1 )Wenn der explizite Konstruktor Meter(Millimeter) mit der passenden Umrechnung existiert, dann kommt da als Ergebnis 2 Meter raus.
Ich schreibe keine Konvertierungskonstruktoren, damit sind Millimeter und Meter unabhängige Größen.
Es wird auch keine geben. Wenn Du in Millimetern rechnen möchtest, dann rechne in Meter um.
Meter Millimeter( int i ) { return Meter( i / 1000 ); } int Meter::AsMilli() { return MeterValue * 1000; } Meter meter = Millimeter( 2000 ); printf( "als Millimetern: %d\n", meter.AsMilli() );Damit entspricht
Meter m = Millimeter( 1000 ) + Meter( 1 );dem, was Du erwartest, ohne dass es eine konkurrierende Meterklasse gibt.
Es gibt nur die Basiseinheit, das lässt man sich leicht merken.
int i = Millimeter( 1000 ) * Butterbrot( 7 );
ganz logisch 7 Unit.Tellerrand schrieb:
Existiert der explizite Konstruktor nicht, so wird Milimeter(1000) einfach als Integer Wert 1000 an den Konstruktor Meter(Integer) übergeben und das Ergebnis ist 1001 Meter.
Aufgrund der fehlenden Beziehung zwischen Millimeter und Meter ist das Ergebnis 1001. Die Einheit ist aber nicht Meter, sondern nicht festgelegt, bzw. "Unit". Eine Zuweisung auf Meter wird also abgelehnt, womit der Programmierer weiß, dass er hier überlegen muss, was er tun muss, um hier zwei kompatible Einheiten zu addieren.
Falsch - du hast den expliziten Konstruktoraufruf schon angegeben, indem du "m = Meter(Millimeter(1000)) + Meter(1);" geschrieben hast - 1000mm werden als int aufgefasst und umgerechnet zu 1000m - und die können klaglos mit 1m addiert werden.
Xin schrieb:
Tellerrand schrieb:
Der Programmierer muss also höllisch aufpassen, welcher Konstruktor nun mit welcher Umwandlung auch funktioniert.
Und das Beispiel zielte darauf ab, dass eine Implementation wie:
Meter m = Meter(Millimeter(1000) / 1000) + Meter(1)
eine potentielle Fehlerquelle ist, da ja jemand auf die Idee kommen könnte und den expliziten Konstruktor Meter(Millimeter) inklusive Umrechnung implementiert.
Und da hast du dann Recht, es kommt ein Wert raus Meter(1,0001), der einfach viel zu klein ist.Auf die Idee hat niemand zu kommen, denn die Typverwaltung wird einmalig geschrieben.
Wenn ein funktionierendes Konstrukt durch fehlerhafte Erweiterungen zu Fehlern neigt, so ist das nicht in der Verantwortung desjenigen, der das funktionierende Konstrukt erstellt hat.
Wer mal eben so unüberlegt "erweitert", ohne das Konzept verstanden zu haben, hat's auch nicht besser verdient.
Das ist kein Problem meiner Klassen, sondern ein ganz allgemeines.Nein, das ist ein Problem für diejenigen, die deine Klassen verwenden wollen - und damit letztlich auch dein Problem.
Xin schrieb:
Tellerrand schrieb:
Fakt ist für mich, dass der Programmierer bei jedem Konstruktoraufruf darauf achten muss welche Umwandlung gemacht wird.
Das Beispiel von Shade of Mine hat durch asInt nunmal den Vorteil, dass der Entwickler diese Arbeit nicht hat. Wenn der Konstruktor Meter(Millimeter) nicht existiert, dann bekommt man das vom Compiler gesagt und man implementiert Meter(Millimeter.asInt())Der Konstruktor Meter( varOfClassMillimeter ) existiert grundsätzlich nicht, also wird varOfClassMillimeter als Int aufgefasst. Wenn Dir das nicht explizit genug ist, ist das okay. Aber fraglich ist mein Vorgehen nicht.
Die Verwandschaft zwischen Metern und Millimetern wirst auch du nicht leugnen können - und die ist imho so eng, daß noch nichtmal eine eigenständige Klasse "Millimeter" gerechtfertigt ist. Also wird dich jeder Nutzer fragen, warum er eine Umrechnung zwischen beidem nicht mitgeliefert bekommt.
Xin schrieb:
Tellerrand schrieb:
Das bringt dann auch den Vorteil mit sich, dass eine spätere Implementation des Konstruktors Meter(Millimeter) keine Auswirkungen auf den schon vorhandenen Code hat.
Ich halte es für falsch und für einen Designfehler, zwei Klassen für eine Einheitenklasse zu implementieren.
Schön, wenn du einsiehst, daß es ein Designfehler ist, aber es ist dein Designfehler.
Xin schrieb:
Tellerrand schrieb:
Was ich mich mittlerweile auch frage:
Was passiert bei einfachen Rechnungen wie Meter(3) * KG(5), welcher Typ kommt da raus. Und wenn da nur ein typloser Wert retuniert, was bringt mir das Framework?
Weil irgendwie sehe ich schon unmengen von verschiedenen TypKlassen und unmengen von unterschiedlichen Operatoren vor mir.Wenn Du Meter*Kilogramm nicht klassifizierst, was Du in der Physik ja durch die Beschreibung "kg*m" tust, wie möchtest Du es sonst ausdrücken, dass es etwas anderes als eine typlose Größe ist? Schau Dir das Template an, dass CStoll im INet gefunden hat. Es ist aufwendig, weil die physikalische Schreibweise in C++ nunmal nicht 'nicht aufwendig' zu beschreiben ist.
Es gibt in C++ kein Verfahren, um typsicher und gleichzeitig einfach zu sein.
Daher muss man sich irgendwo auch überlegen, an welchem Punkt man aussteigen muss (nicht will). Man kann nicht alles abbilden, es wird immer Beispiele geben, die man nicht abbilden konnte.
Aber man kann den Alltag abbilden. Typsicherheit im Alltag, das wäre ein gigantischer Schritt nach vorne.Nochmal: Das Template dort ist womöglich aufwendig umzusetzen - aber einmal erstellt bestimmt nicht aufwendig zu verwenden. Und auf der Basis dieses Templates kann mir der Compiler eine Klasse für jede physikalische Größe anlegen, die ich benötige - und selbständig kontrollieren, ob ich diese Klassen auch korrekt zusammenarbeiten lasse. Du baust dir einen Haufen (fast) identischer Klassen, um ausgewählte Größen damit darstellen zu können - und egal wie weit du gehst, findet sich bestimmt jemand, der über die Grenzen dieser Sammlung hinausgeht (um alle Kombinationen der sieben SI-Basiseinheiten bis zur fünften Potenz zu bilden, benötigst du 76=117649 Klassen - viel Spaß beim Tippen).
-
CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Xin schrieb:
Das Dumme ist halt nur, dass die Informatik sich auch mit Einheiten beschäftigt, die sich durch SI Einheiten nur ganz schlecht ausdrücken lassen, mit denen man aber auch rechnen können muss: Butterbrot, Teppichboden, Krieger.
Ein "Butterbrot" ist keine Einheit, sondern eine Größe - die dazugehörige Einheit wäre "Anzahl".
*lach* Okay... Und wenn ich an die Steckdose packe durchströhmt mich 230 Stück Volts, richtig. Volt ist eine physikalische Größe und Größen werden in "Anzahl" gerechnet.
Du hattest Physik Leistungskurs und kennst nicht den Unterschied zwischen "Größe" und "Einheit"? Die Größe "Butterbrote" wird in "Stück" gemessen, die Größe "Spannung" in "Volt".
Der Unterschied zwischen "Größe" und "Einheit" ist also dass Butterbrote in Stück gemessen wird und Spannung Volt?
Aha. Verstehst Du die Bedeutung von dem, was Du da schreibst?Du begreifst's nicht, oder wie? "Butterbrote" ist eine Größe und wird in "Stück" gemessen, "Spannung" ist auch eine Größe und wird in "Volt" gemessen.
Liebelein... guck doch nochmal nach, was Du alles so schreibst... Du erklärst mir hier, warum Spannung keine Größe ist, sondern eine Einheit. Dann erklärtest Du den Unterschied zwischen Einheit und Größe: nämlich Volt ist eine Größe und Butterbrote ist eine Größe. Wo da der Unterschied zwischen Einheit und Größe liegt, zwei synonymen Begriffen, das weißt vermutlich nur Du.
Konzentriere Dich doch mal darauf, was Du erklären möchtest und nicht nur darauf, einfach zu texten, um Textstellen wie "Du begreifst es nicht, oder wie?" reinzubringen. Ich äußerte vorher schon den Verdacht, dass es Dir vorangig darum geht dagegen zu sein und grade hier textest Du nur unzusammenhängendes Zeugs.
Was Du hier erklärst kann niemand begreifen, es ist nämlich vollkommen ohne inhaltlichen Wert.Am Rande: eine Anzahl wird in Stück gemessen und Stück bedeutet lediglich, dass etwas zählbar ist, gewissermaßen ein Integer. Eine Spannung hingegen wird nicht in Stück gemessen, weil nicht abzählbar. Mehl ist auch nicht abzählbar, darum mißt man es in Gewicht. Egal worin man mißt, man braucht eine Einheit.
Und wenn Du Dir bei Butterbroten unsicher bist, ob Du sie zählen kannst, dann darfst Du Deine Zählklasse auch gerne StückButterbrote nennen, um sie von StückHäuser zu unterscheiden. Und Deine Mehlklasse in GrammMehl, damit Du Deine Pfannkuchen nicht mit GrammUran verwechselst.
Stück ist jedenfalls keine Einheit und darum nenne ich die Einheit, in der ich Butterbrote zähle Butterbrot.
Und wenn ich zwei StückButterbrote und zwei StückHäuser addiere, dann kommen da bei mir vier Unit raus. Nur halt nicht Häuser oder Butterbrote - nur Unit. Und wenn ich 5 GrammUran mit 10 GrammMehl addiere, dann kommen da 15 Unit raus. Als Klassenhersteller habe ich keine Ahnung, was das ist, aber der Entwickler weiß es und kann das nun mit dem entsprechenden expliziten Konstruktor auf GrammSondermüll zuweisen.Ob die Klasse jetzt StückButterbrote heißt, damit auch der Nussallergiker weiß, dass Butterbrote abzählbar sind
oder nur Butterbrot, da ist mir wirklich jede Diskussion zu blöd für.Und der Rest von Deinem seitenlangen Posting wiederholt nur Sachen, die grade Du schon längst beantwortet wissen müsstest, schließlich schreibst Du auf alles eine Antwort, müsstest theoretisch meine Antworten gelesen haben.
Scheinbar nicht. Ergo ist es Zeitverschwendung für Dich Antworten erneut hinzuschreiben.CStoll schrieb:
Xin schrieb:
Meter ist wohl eindeutig eine Größe, die auch als gebrochene Zahl vorkommt. Es von int abzuleiten ist also suboptimal. Das es sich um Beispielcharakter handelt und um keine Produktivlösung, ist wohl eindeutig.
Und wieso verkaufst du uns dann deinen Ansatz bisher als Produktivlösung?
...?
Du entschuldigst, wenn ich Dich auslache? Und zwar lauthals...Erstens... Ich schrieb bereits mehrfach, dass ich einen vergleichbaren (!= identisch) Anzatz für Punkte (Pixelkoordinaten), Distanzen, Flächen und Felder verwende - produktiv. Ich schrieb genauso, dass (bisher) keine Klassen für physikalische Einheiten habe. Das kann man lesen und verstehen. Muss man natürlich nicht.
Zweitens... das ganze ist als Beispiel einer Ableitung von Primitiven gestartet. Ergo ist das ganze in C++ so nicht möglich. Ergo kann dieser Ansatz keine Produktivlösung sein, weil er in C++ nicht kompilierbar ist. Ergo ist es auch überhaupt nicht möglich einem halbwegs denkenden Menschen das als Produktivlösung zu verkaufen. Wenn Du schon überliest, dass die Ableitung von int ein theoretisches Konstrukt auf eine Deiner Fragen ist, dann darf man von einem Moderator in einem C++ Forum wohl erwarten, dass er sich sowas nicht als Produktivlösung versteht.
Drittens... Wer würde bitte schön Meter und Kilogramm als diskrete Größe in einem int speichern und das auch noch öffentlich als Produktivlösung verkaufen wollen?
Ein bißchen Mitdenken, um das offensichtliche zu sehen, könnte nicht schaden. Und wenn man es nicht als offensichtlich genug versteht, erstmal freundlich nachfragen, statt 'hätte ich Dir soviel Intelligenz zugetraut...'-Blabla in Deine Texte zu integrieren.
Sorry, aber sich mit Dir zu unterhalten hat überhaupt keinen Wert. Du suchst nicht weder nach Verbesserungen noch kommst Du Deiner Aufgabe als Moderator eine Diskussion moderat zu gestalten, ausgesprochen gut nach.
Jedenfalls empfinde ich in Fragen eingestreute Sticheleien und allgemein ausschließlich auf Lehrbuchmeinungen zu beharren nicht als moderat, im Gegenteil, statt eine Diskussion zu führen und zu leiten, stellst Du eine Blockade auf, was richtig zu sein hat und alles andere darf nicht.
Es ist in meinen Augen einfach nur dumm, gewonnene Typsicherheit damit schlecht zu reden, dass man sie in Ausnahmen verlieren könnte und trotzdem besser darsteht als zuvor, weil man mitgeteilt bekommt, dass man den Typ verloren hat.
Du beschreibst eine extreme Einstellung und ein extremes Vorgehen gegen andere Überlegungen.Und darum setze ich keine Unterhaltung mit Dir fort.
Shade Of Mine schrieb:
Xin schrieb:
Ich sage, dass die Einheiten nur auf explizite Aufforderung konvertiert werden dürfen. Das bedeutet aber nicht, dass ich irgendwem vorschreibe, wie er seine Konstruktoren zu schreiben hat.
Doch, genau das bedeutet es. Man kann deine Klassen nicht verwenden ohne Typsicherheit zu verlieren wenn man non-explizite CTors hat.
Selbstverständlich kannst Du in Deinen Klassen implizite Konstruktoren benutzen und dennoch meine Klassen verwenden. Meine produktiv eingesetzten Typ-Klassen (Bildschirmkoordinaten usw.) sind so ziemlich die einzigen, die explizite Konstruktoren haben.
Du kannst lediglich meine Klassen nicht ohne explizite Konstruktoren verwenden.
Wenn Du also in Deiner Klasse die Klasse Meter verwendest, ruft Dein impliziter Konstruktor ja explizit meinen Konstruktor auf und alles ist im Reinen.
Schließlich kannst Du Deine Klasse nicht ungefragt auf einen Meter zuweisen.Das einzige, was Du halt nicht machen darfst, ist meinen Klassen implizite Konstruktoren verpassen. Aber wieso solltest Du auf diese Idee kommen - schließlich baust Du in andererleuts Klassen auch nicht ohne Prüfung der Konsequenzen neue Funktionen ein, die das Verhalten der Klasse verändern könnte oder wie oft hast Du schon GTK oder ähnliche Frameworks verändert, weil Du einen neuen Konstruktor hinzufügen wolltest?
Das Hinzufügen von impliziten Konstruktoren zu einer Klasse mit (mindestens einem) expliziten Konstruktor ist ein Schritt, der genau zu überprüfen ist, wenn Du die Prüfung weglässt und es schief geht, dann sehe ich mich den ursprünglichen Entwickler, der seine Klassen mit explicit abgesichert hat, nicht in der Verantwortung, wenn Du seine Absicherung kaputt machst.
-
Xin schrieb:
Du entschuldigst, wenn ich Dich auslache? Und zwar lauthals...
Xin, hau ab, und komm nicht wieder.

-
Da gibts noch ein Zitat zu:
[quote]
Verschwinde und komm nie wieder!
Verschwinde und komm nie wieder!
Verschwinde und komm nie wieder!
Huch haha er ist weg! wir habens geschafft
wir haben ihm gesagt er soll gehen und weg ist er...
[/qoute]
Ob das wirklich so sinnvoll ist(Diese "Antwort")???
-
Erzähl doch bitte noch ein paar Gechichten aus deinem Leben, Xin, wie dus Professoren und anderen ordentlich gegeben hast!
-
Xin schrieb:
Wo da der Unterschied zwischen Einheit und Größe liegt, zwei synonymen Begriffen, das weißt vermutlich nur Du.
Könntest Du das bei Wikipedia gleich noch mitkorrigieren? Die haben vermutlich aus Versehen eine Seite für "physikalische Größe" und eine für "Maßeinheit". Da das das gleiche ist sollte man die Artikel zusammenführen, oder?