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

Xin schrieb:
CStoll schrieb:
OK, dann anders - andere Sprachen mögen eine Unterscheidung zwischen Zuständen des Objekts und Teilobjekten bieten - C++ stellt beides durch Member dar (daß das nicht die perfekte Lösung ist, sehe ich ein).
Dann sieh bitte auch ein, dass C++ beides auch durch Vererbung anbietet und dass das auch nicht immer die perfekte Lösung ist. Trotzdem geht es.
Ich habe noch keine praktische Anwendung (abgesehen von deinen Code-Beispielen) gesehen, wo (öffentliche) Vererbung die bessere Darstellung für interne Zustände wäre.
Xin schrieb:
CStoll schrieb:
Du bist anscheinend der Meinung, dort einen syntaktischen Unterschied zu benötigen - und wirfst darum Zustände mit Verwandschaftsbeziehungen in einen Topf.
...? Lies Dir den Satz nochmal durch...
OK, dann langsam - du versuchst, Teile und Zustände syntaktisch unterschiedlich zu behandeln. Ein neues Sprachmittel dafür zu erfinden wäre sicher eine Lösung, ein bestehendes Sprachmittel (das schon seine vorgegebene Bedeutung hat: Vererbung == "ist-ein") dafür zu verwenden ist die falsche Lösung.
Xin schrieb:
CStoll schrieb:
Tellerrand schrieb:
Ich frage mich also: was spricht überhaupt für die Variante der Vererbung und gegen die Variante der Komposition?
Da muß ich meinen Vorrednern Recht geben - du hast weder ein Argument geliefert, warum die Komposition ungeeignet wäre,
Das könnte zum Beispiel daran liegen, dass ich die ganze Zeit betone, dass sie nicht ungeeignet ist...
CStoll schrieb:
noch eins für die Überlegenheit deines Vererbungsansatzes.
Das wiederum könnte daran liegen, dass ich nicht von "Überlegenheit" spreche, sondern von Alternative.
Du kennst die bisherigen Vorgehensweisen - die sind etabliert und stellen (fast) ideal das dar, was benötigt wird. Und du stellst einen eigenen Ansatz vor, der (aus Sicht fast aller Anwesenden) schlechter auf das Problem passt. Ergo solltest du uns davon überzeugen, daß dein Ansatz mindestens genauso gut ist wie unserer.
Xin schrieb:
CStoll schrieb:
Auf den letzten Seiten hast du nur versucht, Argumente gegen deinen Ansatz zu entkräften (und damit dein Grundprinzip wieder verwässert).
Keine Ahnung, was Du als Verwässerung ansiehst.
Nehmen wir als Beispiel die "if(win)"-Frage: Nachdem du darauf aufmerksam gemacht wurdest, daß sowas möglich ist, hast du erst gegengerudert und op bool privat deklariert - und im nächsten Moment gesagt, daß du keinen privaten op bool hast, sondern nur einen Hinweis, daß man nicht if(win) fragen sollte (was letztlich den selben Effekt hat, aber nicht vom Compiler überprüft werden kann).
Xin schrieb:
Eigentlich habe ich auf den letzten Seiten nur versucht, Dir zu zeigen, dass es Alternativen gibt, die auch Vorteile bieten - eben die Typsicherheit.
Um Typsicherheit zu gewährleisten, brauche ich keine Vererbungsbeziehungen. Die bekomme ich mit einer eigenen (freistehenden) Flag-Klasse genausogut.
Xin schrieb:
Bloß nicht gucken, ob da vielleicht ein Vorteil drin verborgen sein könnte. Ich beschäftige mich neutral damit: Komposition gut, Vererbung - auch nicht schlecht.
Das "Komposition gut" fällt Dir überhaupt nicht auf, oder? Das ist nichts, wo Du dagegen sein könntest.
Noch striktere Klassifizierung erforderlich? Sehr gut, weil Disziplin zwangsverordnet.Wenn das deine Meinung ist, hast du sie bisher sehr gut versteckt - für mich sah das eher nach "Komposition brauchbar - Vererbung wesentlich besser".
Xin schrieb:
Ich führe hier keinen Wettstreit gut gegen böse. Es geht hier um eine Alternative. Gut gegen genauso gut. Vielleicht gut gegen nicht ganz so gut in C++. Vielleicht auch gut gegen etwas besser, wenn man sich damit auseinandersetzt. Ich habe damit nur begrenzte Erfahrung, ich leite nicht grundsätzlich ab. Ich leite nur ein Objekt von seinen Flags ab und überlege, ob ich neue Klassen aus Vorhandenen sinnvoll zusammenvererben kann. Was mir nicht sinnvoll erscheint, kommt als Member rein.
Die Ableitung von Flags mag vielleicht technisch möglich sein, aber sie widerspricht immer noch den OOP-Prinzipien (aber wenn du nicht objektorientiert arbeitest, ist das natürlich kein Problem). Die Definition von Hilfsklassen, nur um mehrere gleichartige Eigenschaften in ein Objekt zu packen, halte ich für unsinnig und fehleranfällig. Und du hast immer noch nicht klargestellt, was der entscheidende Vorteil davon ist - von kryptischeren Quelltexten mal abgesehen.
-
Der unterhaltungswert ist gleich null, weil ihr immer viel zu viel schreibt. das will keiner lesen
-
Ich lese nur CStolls Posts, da er Xins zeug sinnvoll filtert.
-
CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Schön, wenn du eine Sprache hast, die zwischen Zuständen und Teilobjekten unterscheiden kann. C++ kann das leider nicht, also brauchst du gar nicht versuchen, es dazu zu bringen.
Super Einstellung. "Ich" kann das nicht, also brauchst "Du" es nicht zu versuchen.
Ich versuche es trotzdem. Sich derart dagegen zu wehren bringt aber nix, ich zwinge schließlich niemanden hier, es zu nutzen.Doch, du versuchst krampfhaft, mir zu erklären, daß dein Ansatz besser ist.
Vielleicht macht Dir diese Antwort verständlich, wie krampfhaft ich versuche Dich von etwas zu überzeugen. Denk selbst drüber nach, oder lass es - es zwingt Dich niemand.
-
@Xin
ich empfehle dir folgendes Buch:
Design Patterns | ISBN: 0201633612
Insbesondere das Kapitel über Vererbung vs. Delegation.
Wenn du es gelesen hast und immer noch von "class Window: public WindowsFlags" überzeugt bist, dann solltest du es nochmal lesen und evtl. dann nochmal.
Ist echt ganz schön stur von dir zu behaupten, es sei aus OO Sicht völlig OK, obwohl dir hier schon 100x gezeigt wurde, dass das Murks ist.Gruß
mathik
-
mathik schrieb:
@Xin
ich empfehle dir folgendes Buch:
Design Patterns | ISBN: 0201633612
Insbesondere das Kapitel über Vererbung vs. Delegation.Auch das Buch steht als Standardwerk natürlich auch hier und ist längst gelesen.
mathik schrieb:
Wenn du es gelesen hast und immer noch von "class Window: public WindowsFlags" überzeugt bist, dann solltest du es nochmal lesen und evtl. dann nochmal.
...und vor allem immer brav im Gleichschritt marschieren und auf keinen Fall Wege suchen, die nicht irgendwer in einem Buch für gut beschrieben hat.
Die Gang Of Four hat die Design Patterns beschrieben, die Patterns sind gut, aber das ist keine Religion und die Patterns sind keine steingemeißelten Gebote. Auch wenn manche es so auffassen.
Erfahrung ist mehr als ein Buch gelesen zu haben. Erfahrung heißt Dinge auszuprobieren und das heißt auch Dinge auf Möglichkeiten abzuklopfen, die der Masse nicht zusagen.
Neues Wissen findet sich nicht in sauberen Büchern, sondern im Dreck dazwischen.Und da Du den Thread gelesen hast, weißt Du ja, dass das Ding, dass ich abklopfe eine Mischung aus privater und öffentlicher Vererbung ist und "class Window : public WindowFlags" eine vereinfachte Abwandlung davon ist.
Du hast sicherlich auch gelesen, dass der Fragesteller Möglichkeiten suchte und eine Möglichkeit habe ich angeboten, ob es CStoll oder Dir im Detail gefällt oder nicht. Die angebotene Möglichkeit muss nicht perfekt sein, um eine Möglichkeit zu sein. "int(Flags) & WFLG_FULLSCREEN" ist das übliche Vorgehen und das ist ebenfalls sehr weit entfernt von perfekt.
Wie Du auch bereits gelesen hast, stelle ich meinen Sourcecode lediglich als Möglichkeit, nicht als perfekte Möglichkeit dar.Vollkommen unabhängig davon, halte ich die Möglichkeit Eigenschaften scharf zu klassifizieren und durch Vererbung weiterzureichen, für eine SEHR interessanten Ansatz, Disziplin in der Programmierung zu erzwingen - vollkommen unabhängig davon, was in DesignPatterns oder Scott Meyers Büchern steht.
Zumindest bei Scott Meyer weiß ich, dass er seine Bücher nicht als Gott gegebene Regeln ansieht, sondern als Empfehlungen. Und als Empfehlungen sind seine Bücher verdammt gut.mathik schrieb:
Ist echt ganz schön stur von dir zu behaupten, es sei aus OO Sicht völlig OK, obwohl dir hier schon 100x gezeigt wurde, dass das Murks ist.
Mir wurde schon viel gezeigt und diese Tatsache wird nicht selten auch wieder vergessen, wenn sich die allgemeine Perspektive bewegt hat. Mir 100x das selbe zu zeigen, ein ganzes Forum gegen mich zu haben, nichtmals die Paprikaallergie von CStolls Oma beeindruckt mich diesbezüglich im Entferntesten. Ein einziges sauber und konstruktiv begründetes Argument hingegen kann Welten bewegen.
Shade hat ein Argument gebracht und CStoll hat mir die Augen geöffnet für mein Mißverständnis, so dass ich beiden zugestimmt habe, dass die Komposition in C++ wohl die bessere Wahl ist (Seite 7 afair). Derartige Details interessieren aber offenbar auch dann nicht, wenn ich es wiederhole, weil man sonst nicht weiter so schön gegen mich sein kann.
Den Punkt, den Shade angeführt hat, ist an meinem Source unschön, aber kein K.O.-Kriterium, da man es mit etwas Mehraufwand entsprechend umgehen kann und selbst ein operator bool() in einem Fenster kein Problem darstellt, dass im Alltag eine ernstzunehmende Gefahr darstellt.
Die Möglichkeit bleibt bestehen, ein Fenster als Erweiterung zu seinen Flags zu sehen, auch wenn das ungewöhnlich ist und in dem Source, den ich als Möglichkeit angeboten habe, der operator bool() nicht gefällt. Die Möglichkeit nicht optimal, aber definitiv auch nicht schlecht.
Ansonsten: Lies den Thread und lies, was ich schreibe, nicht was CStoll und/oder Du daraus interpretierst.
-
Xin schrieb:
...und vor allem immer brav im Gleichschritt marschieren und auf keinen Fall Wege suchen, die nicht irgendwer in einem Buch für gut beschrieben hat.
Einfach mal ohne werten zu wollen:
Krankhaft gegen den Mainstream sein ist genauso falsch wie krankhaft mit dem Mainstream sein zu wollen.
Der Mensch hat viele Idee - 99% davon ist Schrott. Es sind die 1% die den Unterschied machen. Diese 1% sind die guten Ideen.
Es ist sehr sehr einfach eine Idee zu haben die anders ist als alle gängigen. Das ist absolut kein Problem. Ich sehe mir ein Auto an und denke mir einfach eckige Räder dazu - tada - ich hab ein Auto das komplett anders ist als alle anderen.
Das Problem ist nun zu erkennen ob diese Idee eine von den 99% oder eine von den 1% ist.
Nun zu diesem konkreten Beispiel:
Deine Idee ist anders als der Mainstream. Aber ist sie besser oder gleichwertig? Ein Haufen Leute hat einen Haufen Gründe genannt warum sie schlechter ist und du kannst keinen nennen warum sie besser ist. Du kannst lediglich die Argumente warum es schlechter ist widerlegen - selbst wenn du aber alle widerlegst bleibt ein Problem bestehen:Es ist nicht besser als die herkömmliche Lösung - wohl aber anders. Und wenn etwas nur anders aber nicht besser ist, ist es defakto schlechter da es weniger Know-How hier gibt.
Deshalb sollte man immer ganz vorsichtig sein wenn man eine Idee als "gegen den Mainstream" bezeichnet. Denn meistens ist das Ziel einer solchen Idee einfach nur anders zu sein.
-
Xin schrieb:
Shade hat ein Argument gebracht und CStoll hat mir die Augen geöffnet für mein Mißverständnis, so dass ich beiden zugestimmt habe, dass die Komposition in C++ wohl die bessere Wahl ist (Seite 7 afair). Derartige Details interessieren aber offenbar auch dann nicht, wenn ich es wiederhole, weil man sonst nicht weiter so schön gegen mich sein kann.
[...]
Die Möglichkeit bleibt bestehen, ein Fenster als Erweiterung zu seinen Flags zu sehen, auch wenn das ungewöhnlich ist und in dem Source, den ich als Möglichkeit angeboten habe, der operator bool() nicht gefällt. Die Möglichkeit nicht optimal, aber definitiv auch nicht schlecht.Die Sache ist doch die, dass deine Probleme, die du offenbar auch siehst, genau deshalb entstanden sind, weil dein Code diesen aufgestellten Thesen widerspricht.
Das ist doch genau der Grund, warum Meyers, Sutter und wie sie alle heißen sowas in ihren Büchern schreiben. Weil sonst Probleme auftreten wie sie hier vielfach aufgedeckt wurden.
Das bool()-Problem z.B. tritt doch auf, weil deine public-Vererbung eben keine "IST-EIN"-Beziehung darstellt.
-
Xin schrieb:
Shade hat ein Argument gebracht und CStoll hat mir die Augen geöffnet für mein Mißverständnis, so dass ich beiden zugestimmt habe, dass die Komposition in C++ wohl die bessere Wahl ist (Seite 7 afair). Derartige Details interessieren aber offenbar auch dann nicht, wenn ich es wiederhole, weil man sonst nicht weiter so schön gegen mich sein kann.
Auch wenn Du Dir das anscheinend gern selbst einredest, niemand ist aus Prinzip gegen Dich. Das hast Du Dir ganz allein zuzuschreiben. Behauptung.
Begründung:
1. Genau diese Behauptung "alle sind gegen mich" (Arroganz, "ich bin so toll und wichtig, daß ich es wert bin, daß jemand gegen mich ist und dafür seitenweise schreibt")
2. Äußerungen wie "class DeppenWindow"
3. Äußerungen wie "die kids, ihre eltern, blabla"Ich zitiere einen Mathematikversager: "Schon die Voraussetzungen sind falsch"
Falsche Voraussetzungen sind u.a.:
- "WindowFlags sind Windows"
- "Ein Auto kann eine Farbe sein" <- spätestens hier krieg ich Pipi in die AugenÜbrigens habe ich Deine Zustimmung nicht auf Seite 7 finden können. Daher wäre es sehr nett, wenn Du Dich mal nicht auf dein Gedächtnis verlassen würdest.
Nehmen wir an, sie steht irgendwo anders. Das heißt, Du sagst, daß Deine Alternative "schlechter" ist. Dann mußt Du Dich dafür rechtfertigen, daß Du sie trotzdem verwendest. Da Du natürlich die "bessere" Alternative verstehst, kann es schonmal nicht an mangelnden (Programmier-)Fähigkeiten liegen. Jetzt wirds aber schon hakelig...
-
Shade Of Mine schrieb:
Xin schrieb:
...und vor allem immer brav im Gleichschritt marschieren und auf keinen Fall Wege suchen, die nicht irgendwer in einem Buch für gut beschrieben hat.
Einfach mal ohne werten zu wollen:
So kann man diskutieren.
Shade Of Mine schrieb:
Krankhaft gegen den Mainstream sein ist genauso falsch wie krankhaft mit dem Mainstream sein zu wollen.
Ich bin nicht krankhaft gegen den Mainstream, denn ich programmiere in den meisten Dingen ja auch nicht anders, als andere Entwickler auch. Das vielleicht mal explizit ausgesprochen - ich bin kein Crack, der möglichst schwer verständlichen Code produzieren will - absolut das Gegenteil ist der Fall.
Wo ich allerdings einen Unterschied ziehe ist, dass ich mich mit meinem Werkzeug - der Programmiersprache - sehr detailiert auseinandersetze und mich auch mit den Dingen beschäftige.
Das schließt auch Techniken ein, die andere als schlecht beschreiben und ich mache mir auch Gedanken, zu Dingen, die mit C++ nicht oder nicht einfach beschreibbar sind.
Vieles ist zurecht als schlecht verrufen und Bücher wie Design Patterns oder die Scott Meyer Bücher sind wertvolle Hilfen, um gut zu programmieren. Sie wurden dafür geschrieben eine Hilfe für gute Programmierung zu sein, aber nicht um als die einzige Wahrheit für gute Programmierung zu gelten.Was in einem Buch steht, muss weder richtig sein, noch muss ein gutes Buch ein Dogma darstellen. Der Irrglaube, dass Bücher, besonders bei hervorragenden Büchern, kritiklos hinzunehmen sind, ist weit verbreitet. Auch "hervorragend" bedeutet noch nicht "uneingeschränkt gültig".
Alleine die Tatsache jedes Fachbuch sofort und grundsätzlich in Frage zu stellen unterscheidet mich von vielen anderen. Ich sehe Quellen wie Bücher oder dieses Forum als Inspiration, nicht als einzige Wahrheit.
Shade Of Mine schrieb:
Nun zu diesem konkreten Beispiel:
Deine Idee ist anders als der Mainstream. Du kannst lediglich die Argumente warum es schlechter ist widerlegen - selbst wenn du aber alle widerlegst bleibt ein Problem bestehen: wenn etwas nur anders aber nicht besser ist, ist es defakto schlechter da es weniger Know-How hier gibt.Hier laufen zwei Dinge zusammen. Das eine ist die Klasse Flags und das andere die Vererbung. Die Klasse halte ich nachwie vor für richtig. Was die Vererbung in C++ angeht, so halte ich die Komposition aufgrund Deines Arguments bei meinem Beispiel-Code inzwischen für besser.
Trennt man die die Flags als Variable von den einzelnen Flags als Werten und somit die öffentlichen und privaten Teile, so sehe ich hier die Möglichkeit, dass das ganze besser ist.
Es ist nicht schwer besser als 'Flags & DEFINE_FULLSCREEN' zu sein.Shade Of Mine schrieb:
Deshalb sollte man immer ganz vorsichtig sein wenn man eine Idee als "gegen den Mainstream" bezeichnet. Denn meistens ist das Ziel einer solchen Idee einfach nur anders zu sein.
Meinen Ruf habe ich in diesem Forum ja bereits weg, ein kleines Rudel "Unregistrierter" sorgt bei nahezu jedem Posting dafür, dass das auch ja nicht vergessen wird.
Fakt ist, dass dieses Vorgehen nicht den Mainstream darstellt und damit "anders" ist. Mir geht es nicht, darum anders zu sein. Ich gebe mein Wissen weiter und oder eben hier eine Alternative zur Diskussion. Und ich stelle fest, dass daran nur eine Minderheit interessiert ist. Das ist enttäuschend, aber auch nicht unbedingt wichtig.
Hier geht es mir darum, universell benutzte Datentypen wie int zu vermeiden, darum die Klasse Flags. Das kann man akzeptieren oder lassen oder sich immer wieder auf die Vererbung der Flags stürzen, obwohl in dem Thema längst Einigkeit herrscht.Das Thema Vererbung als Memberkonzept ist unabhängig davon, eine interessante Möglichkeit anders zu programmieren, der ich durchaus gute Chancen für ein besseres Programmieren zuspreche. Aufwändiger, aber besser. Und besser rechtfertigt für mich bei vielbenutzten Klassen nahezu jeden Aufwand.
-
Xin schrieb:
Mir geht es nicht, darum anders zu sein. Ich gebe mein Wissen weiter und oder eben hier eine Alternative zur Diskussion. Und ich stelle fest, dass daran nur eine Minderheit interessiert ist. Das ist enttäuschend, aber auch nicht unbedingt wichtig.
Hier geht es mir darum, universell benutzte Datentypen wie int zu vermeiden, darum die Klasse Flags. Das kann man akzeptieren oder lassen oder sich immer wieder auf die Vererbung der Flags stürzen, obwohl in dem Thema längst Einigkeit herrscht.Auch wenn es unwichtig ist: Mich hast du zum nachdenken gebracht, auch wenn ich sicherlich nicht mir nix dir nix auf deine Methode umsteigen werde. Und interessant ist dein Konzept alle mal, jedenfalls wenn ich es richtig verstanden hab

-
Badestrand schrieb:
Xin schrieb:
Mir geht es nicht, darum anders zu sein. Ich gebe mein Wissen weiter und oder eben hier eine Alternative zur Diskussion. Und ich stelle fest, dass daran nur eine Minderheit interessiert ist. Das ist enttäuschend, aber auch nicht unbedingt wichtig.
Auch wenn es unwichtig ist: Mich hast du zum nachdenken gebracht, auch wenn ich sicherlich nicht mir nix dir nix auf deine Methode umsteigen werde. Und interessant ist dein Konzept alle mal, jedenfalls wenn ich es richtig verstanden hab


Wenn man Menschen nicht dazu veranlassen kann nachzudenken, so ist das nicht wichtig. Es ist nur ein Angebot.
Wenn das Angebot inspirieren konnte, so ist mir das Feedback schon wichtig, denn sonst bräuchte ich es nicht zu probieren.Dafür musst Du nicht Deine Programmierung nicht ändern. Sich bewußt zu machen, was man tut und was dadurch dass man es tut auf der anderen Seite unterlässt, das ist eingentlich der wichtigste Punkt.
Man kann sich nur dann dazu entscheiden, auch eigene Alternativen zu bauen, wenn frei genug im Denken ist, um überhaupt auf den Gedanken zu kommen, dass Alternativen möglich sind.
-
Xin schrieb:
Meinen Ruf habe ich in diesem Forum ja bereits weg, ein kleines Rudel "Unregistrierter" sorgt bei nahezu jedem Posting dafür, dass das auch ja nicht vergessen wird.
versteh ich nicht, in diesem thread hat doch kein unreg was zum thema beigetragen.
vielleicht solltest du mal von deinem ego trip runterkommen und einsehen dass dein schlechter ruf vielleicht davon verursacht wird, dass du hier so viel müll redest, das versuchst mit fadenscheinigen argumenten aufrechtzuerhalten und wenn das nicht klappt anfängst andere zu beleidigen?nur zur info: in diesem forum lesen auch viele professionelle entwickler mit, würde mich nicht wundern wenn du dir mit den letzten beiden threads jede menge jobchancen verbaut hast, auch wenn du es vermutlich niemals bestätigt bekommen wirst

-
unregistrierter schrieb:
Xin schrieb:
Meinen Ruf habe ich in diesem Forum ja bereits weg, ein kleines Rudel "Unregistrierter" sorgt bei nahezu jedem Posting dafür, dass das auch ja nicht vergessen wird.
versteh ich nicht, in diesem thread hat doch kein unreg was zum thema beigetragen.
Gratuliere, Du hast die Kritik verstanden und gleichzeitig bestätigt.

-
Xin schrieb:
Meinen Ruf habe ich in diesem Forum ja bereits weg, ein kleines Rudel "Unregistrierter" sorgt bei nahezu jedem Posting dafür, dass das auch ja nicht vergessen wird.
Leute werden nicht aufgrund ihres namens verarscht, sondern aufgrund ihres verhaltens.
-
Xin schrieb:
unregistrierter schrieb:
Xin schrieb:
Meinen Ruf habe ich in diesem Forum ja bereits weg, ein kleines Rudel "Unregistrierter" sorgt bei nahezu jedem Posting dafür, dass das auch ja nicht vergessen wird.
versteh ich nicht, in diesem thread hat doch kein unreg was zum thema beigetragen.
Gratuliere, Du hast die Kritik verstanden und gleichzeitig bestätigt.

du verstehst auch jeden post so, damit du ihn dir so zurechtrücken kannst wie du willst oder?

-
Xin schrieb:
CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Schön, wenn du eine Sprache hast, die zwischen Zuständen und Teilobjekten unterscheiden kann. C++ kann das leider nicht, also brauchst du gar nicht versuchen, es dazu zu bringen.
Super Einstellung. "Ich" kann das nicht, also brauchst "Du" es nicht zu versuchen.
Ich versuche es trotzdem. Sich derart dagegen zu wehren bringt aber nix, ich zwinge schließlich niemanden hier, es zu nutzen.Doch, du versuchst krampfhaft, mir zu erklären, daß dein Ansatz besser ist.
Vielleicht macht Dir diese Antwort verständlich, wie krampfhaft ich versuche Dich von etwas zu überzeugen. Denk selbst drüber nach, oder lass es - es zwingt Dich niemand.
Schön, daß du jetzt anfängst, meine Beiträge inhaltlich zu ignorieren.
OK, fassen wir nochmal die bisherigen Beispiele zusammen, die laufen alle auf einen ähnlichen Denkfehler hinaus: Du kannst mit Ableitung die Fähigkeiten einer Klasse erweitern, aber nicht einschränken.
-
WindowFlags vs. Window:
Die Klasse WindowFlags hat einen operator bool() (und auch wenn du das "s" noch so sehr betonst, ein einzelnes Flag ist auch von diesem Typ), die Klasse Window als bool zu betrachten ist sinnlos (und wenn nicht, dann mit einer völlig anderen Semantik als für WindowFlags). Da ist es egal, ob du eine technische (op bool ist privat und der Compiler beschwert sich, wenn man es nutzen will) oder konzeptionelle (irgendwo in der Doku steht "benutze nie 'if(win)...'") Einschränkung hast - du hast eine Einschränkung.
(und im Ernstfall sind mir technische Einschränkungen lieber) -
Ableitungen von int:
Du hast alle Maßangaben (Längen, Gewichte etc) von int abgeleitet, um Schreibarbeit zu sparen. Aber damit hast du gleichzeitig massenweise Mehraufwand, um sie vernünftig nutzen zu können: -
Alle Operatoren liefern int-Werte, also brauchst du entweder Typumwandlungen von int in deine Typen (aber dann geht die Typsicherheit verloren, wenn du beliebig Gewichte und Längen miteinander verwursten kannst) oder eigene überladene Operatoren (aber dann brauchst du die Verwandtschaft mit int nicht mehr)
-
btw, op+ und op- zu überladen mag ja noch recht einfach sein, aber bei op* und op/ wird's dann haarig (die schlucken zwei beliebige Maßangaben und geben eine völlig andere Angabe wieder heraus) - davon, was bei op& und Co. rauskommen sollte, will ich gar nicht anfangen.
(erzähl mir jetzt bitte nichts von Templates - ich kenne eine Template-Lösung dafür, aber die braucht keine Vererbung von int) -
Wertekombination durch Vererbung:
In den wenigstens Fällen sind die Attribute eines Objekts unabhängig voneinander (die Maximalgeschwindigkeit eines Autos hängt von der Motorleistung ab, die linke obere Ecke eines Fensters von der rechten oberen Ecke etc). Die einzelnen Basisklassen sind aber konzeptionell unabhängig voneinander - also mußt du in der abgeleiteten Klasse dafür sorgen, daß sie sich konsistent zueinander ändern.
PS: Die Allergie hatte ich übrigens erwähnt, weil du mit den Allergiewarnungen angefangen hast - es gibt halt auch Menschen, die unter mehr leiden als einem (eher harmlosen) Heuschnupfen (btw, ich kenne auch jemanden mit einer Nussallergie). Und die sind dankbar, wenn sie rechtzeitig über (potentiell) gefährliche Nahrungsmittel informiert werden.
PPS: Mich hast du übrigens auch zum Nachdenken gebracht - mit dem Ergebnis, daß ich deine Lösung nach längerem Nachdenken als unsinnig eingestuft habe.
-
-
CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Xin schrieb:
CStoll schrieb:
Schön, wenn du eine Sprache hast, die zwischen Zuständen und Teilobjekten unterscheiden kann. C++ kann das leider nicht, also brauchst du gar nicht versuchen, es dazu zu bringen.
Super Einstellung. "Ich" kann das nicht, also brauchst "Du" es nicht zu versuchen.
Ich versuche es trotzdem. Sich derart dagegen zu wehren bringt aber nix, ich zwinge schließlich niemanden hier, es zu nutzen.Doch, du versuchst krampfhaft, mir zu erklären, daß dein Ansatz besser ist.
Vielleicht macht Dir diese Antwort verständlich, wie krampfhaft ich versuche Dich von etwas zu überzeugen. Denk selbst drüber nach, oder lass es - es zwingt Dich niemand.
Schön, daß du jetzt anfängst, meine Beiträge inhaltlich zu ignorieren.
Sorry, aber inhaltlich kam nicht mehr viel und Du spielst hier ein unsinniges Spiel mit mir: Antworten, um dagegen zu sein. Dass ich seit x Seiten Dir zustimme, dass die Komposition in C++ besser als die Ableitung ist, ignorierst Du und behauptest auch noch, dass ich krampfhaft versuche zu erklären, dass Vererbung besser wäre.
Wo soll ich denn einen Grund sehen, Dich da inhaltlich überhaupt zu beachten.CStoll schrieb:
OK, fassen wir nochmal die bisherigen Beispiele zusammen,
Wir? Wer ist "wir"?
Ich fasse es mal so auf, dass Du zusammenfasst und ich ergänze.
CStoll schrieb:
WindowFlags vs. Window:
Die Klasse WindowFlags hat einen operator bool() (und auch wenn du das "s" noch so sehr betonst, ein einzelnes Flag ist auch von diesem Typ),Hier ignorierst Du erstens mehrfach genannte Möglichkeit das durch Trennung in zwei Klassen zu ändern... und die oben genannte Tatsache, dass ich die Komposition seit Seite iirc 7 als die bessere Möglichkeit ansehe...
CStoll schrieb:
die Klasse Window als bool zu betrachten ist sinnlos (und wenn nicht, dann mit einer völlig anderen Semantik als für WindowFlags). Da ist es egal, ob du eine technische (op bool ist privat und der Compiler beschwert sich, wenn man es nutzen will) oder konzeptionelle (irgendwo in der Doku steht "benutze nie 'if(win)...'") Einschränkung hast - du hast eine Einschränkung.
(und im Ernstfall sind mir technische Einschränkungen lieber)Welche technische Einschränkung bietet Dir denn ein "int Flags", die "übliche" und bewerte "Technik".
Selbst, wenn ich ableite (Komposition in C++ besser, S. 7. blahblah), bin ich besser eingeschränkt, als mit einem popligen int, dass mangels Typ eigentlich alles darstellen kann.
Halt stop, nicht alles, es stellt zum Beispiel definitiv keine Zahl dar. Müsstest Du hier nicht operator + und operator -, und operator * und operator / erstmal abschalten, bevor Du hier was von technischen Einschränkungen schreibst?Schließe Dein Scheunentor und dann reden wir weiter. Und um Dein Scheunentor zu schließen, wirst Du vermutlich wieder bei class WindowFlags landen.
Noch ein "Detail", das in Deiner "Zusammenfassung" fehlt.
CStoll schrieb:
Ableitungen von int:
Du hast alle Maßangaben (Längen, Gewichte etc) von int abgeleitet, um Schreibarbeit zu sparen. Aber damit hast du gleichzeitig massenweise Mehraufwand, um sie vernünftig nutzen zu können:Uii... Mehraufwand, um Typsicher zu arbeiten?!
Hier liegen die Prioritäten definitiv anders. Aber wer überhaupt Klassen nutzt, sollte sich nicht über Mehraufwand beschweren, denn früher wurde sowas alles auch problemlos mit Arrays gelöst. Für die Typsicherheit hat man sich dann doch für den Mehraufwand der Klassen entscheiden und sicherlich möchtest Du heute auch nicht mehr zu Byte-Arrays zurückkehren.CStoll schrieb:
Alle Operatoren liefern int-Werte, also brauchst du entweder Typumwandlungen von int in deine Typen (aber dann geht die Typsicherheit verloren, wenn du beliebig Gewichte und Längen miteinander verwursten kannst) oder eigene überladene Operatoren (aber dann brauchst du die Verwandtschaft mit int nicht mehr)
Ich sehe in der Verwandschaft mit "Zahl" nichts schlechtes.
int p = Quarktaschen( 3 ) + Zitronenkuchen( 2 ) + Kaesekuchen( 5 );
cout "Genug Futter für " << p << "Personen da." << endl;CStoll schrieb:
btw, op+ und op- zu überladen mag ja noch recht einfach sein, aber bei op* und op/ wird's dann haarig (die schlucken zwei beliebige Maßangaben und geben eine völlig andere Angabe wieder heraus) - davon, was bei op& und Co. rauskommen sollte, will ich gar nicht anfangen.
Damit solltest Du aber anfangen, weil es die Qualität Deiner Software erhöht.
5 Kilogramm * 20 Meter / 4Sekunde^2 ergibt nunmal nicht 25.CStoll schrieb:
(erzähl mir jetzt bitte nichts von Templates - ich kenne eine Template-Lösung dafür, aber die braucht keine Vererbung von int)
Ich erzähle hier nichts von Templates - ich habe keine, aber ich bin gespannt, Deine Templatelösung zu sehen, die mir die Verbindung von Newton zu den Grundeinheiten erstellt.
CStoll schrieb:
[*]Wertekombination durch Vererbung:
In den wenigstens Fällen sind die Attribute eines Objekts unabhängig voneinander (die Maximalgeschwindigkeit eines Autos hängt von der Motorleistung ab, die linke obere Ecke eines Fensters von der rechten oberen Ecke etc). Die einzelnen Basisklassen sind aber konzeptionell unabhängig voneinander - also mußt du in der abgeleiteten Klasse dafür sorgen, daß sie sich konsistent zueinander ändern.Stimmt. Und wo liegt das Problem?
Mal abgesehen davon, dass die Relation zwischen zwei Eigenschaften bei Vererbung und Komposition beschrieben werden muss - woher soll der Computer sie schließlich wissen.
Das ist hier ungefähr so wichtig, wie die Paprikaallergie Deiner Oma.CStoll schrieb:
PS: Die Allergie hatte ich übrigens erwähnt, weil du mit den Allergiewarnungen angefangen hast - es gibt halt auch Menschen, die unter mehr leiden als einem (eher harmlosen) Heuschnupfen (btw, ich kenne auch jemanden mit einer Nussallergie). Und die sind dankbar, wenn sie rechtzeitig über (potentiell) gefährliche Nahrungsmittel informiert werden.
...
Wer als Nussallergiker Nüsse kauft, braucht den Hinweis nicht. Sollte er ihn doch brauchen, ist er vorrangig Intelligenzallergiker. Wann begreifst Du, dass die Aussage sich nicht auf die Allergie bezieht, sondern auf die Intelligenzleistung, die erforderlich ist, dass man als Nussallergiker nunmal keine Nüsse kauft, selbst wenn da keine Warnung auf der Packung steht...
Deine Oma kauft ja auch keine Paprika, wenn sie dagegen allergisch ist und Du wirst vermutlich niemals das Gras eines Fussballstadions pflegen, obwohl weder auf Paprika, noch auf dem Rasen Warnhinweise für Allergiker angebracht sind...CStoll schrieb:
PPS: Mich hast du übrigens auch zum Nachdenken gebracht - mit dem Ergebnis, daß ich deine Lösung nach längerem Nachdenken als unsinnig eingestuft habe.
Das 'längere Nachdenken' glaube ich Dir ehrlich gesagt nicht. Wer nachdenkt stellt Fragen und keine Behauptungen auf. Wer nachdenkt nimmt Informationen auf. Du konzentrierst Dich seit mehreren Seiten darauf, gegen etwas zu sein, dass nicht mehr zur Debatte steht, weil wir uns darüber schon einig waren. Es war Dir offenbar trotz längerem Nachdenken nicht möglich die unterschiedliche Themen zwischen Vererbung für Flags, WindowFlags und Typsicherung entsprechend voneinander gelöst zu besprechen.
Das Thema Vererbung für Flags ist seit x Seiten geklärt, erledigt, vorbei.
Du drängst mich mit jedem Posting in eine Position, die ich gar nicht mehr vertrete (Seite 7... Komposition besser in C++... jaddajadda...)
Und dass einige Dinge hier hypothetischer Natur sind, sollte Dir spätestens daran auffallen, wenn ich "class Meter : public int" schreibe, weil in C++ es nicht möglich ist von Primitiven abzuleiten.Deine "Zusammenfassung" ist eine Zusammenfassung Deiner Sichtweise. Da ist alles drin, was Du brauchst, um dagegen zu sein, aber nichts, was darauf hinweist, dass Du meine Texte gelesen hättest.
Das hat nichts mit denken zu tun, sondern dass ist einfach nur weiter texten, hübsch kombiniert mitCStoll schrieb:
Doch, du versuchst krampfhaft, mir zu erklären, daß dein Ansatz besser ist.
Ich denke, Dich hier inhaltlich zu ignorieren, ist eine sehr freundliche Form, auf einen derartigen Diskussionsstil zu reagieren.
Vielleicht kommt es in der x. Wiederholung bei Dir an: Ich zwinge Dich nicht, etwas zu nutzen. Ich zwinge Dir auch nicht ein Verständnis für Typsicherheit auf. Du kannst meinetwegen programmieren was und wie Du willst.
Alles, was ich hier angeboten habe, war eine Möglichkeit, typsicherer zu arbeiten. Diese Möglichkeit dient als Inspirationshilfe, die weiterhin verbesserungsfähig ist, was auch schon x mal geschrieben wurde.
Und ich habe keinen Bock auch nur eine weitere Seite in diesem Thread, Dich darauf aufmerksam zu machen.
Und darum habe ich auch kein Problem damit, dass Du Dich von mir inhaltlich ignoriert fühlst.
-
Vielleicht kommt es bei der xten Wiederholung bei Dir an:
1. Auf Seite 7 kann ich Deine Zustimmung, Komposition sei in dem Fall besser als Vererbung, nicht finden. Also such sie gefälligst bitteschön und schreib endlich die richtige Seitenzahl hin! Ebenfalls ist es möglich, daß Du Dich wie üblich diffus ausgedrückt hast- dann zitier einfach Deine Zustimmung mal!
2. Deine indirekte Selbstbeweihräucherung ist dumm. Diesmal keine Begründung mehr für meine Behauptung.
-
Xin schrieb:
int p = Quarktaschen( 3 ) + Zitronenkuchen( 2 ) + Kaesekuchen( 5 );
cout "Genug Futter für " << p << "Personen da." << endl;int p = Quarktaschen( 3 ) + Zitronenkuchen( 2 ) + Kaesekuchen( 5 ); cout << "Genug Futter für " << p << "Personen da." << endl;