Konstruktor und Virtuelle Methoden
-
asc schrieb:
gleichseitigesDreieck(float seite) : Dreieck(xxx, yyy), // <-- xxx,yyy entsprechend austauschen a(seite) {}Das sieht irgenwie getrickst aus. Gibt es keine andere möglichkeit?
Den das Dreieck(x, y) benötig man ja gar net. Denn die Variablen von Dreieck will ich nicht benutzen.
-
Da sind sie deswegen trotzdem. Genau sowas verrät dir meist einen Designfehler.
Du könntest gleichseitigesDreieck ja auch von Figur ableiten. Dann hast du das Problem nicht.
-
Gegenwärtig hast du:
Figur | Dreieck | gleichseitigesDreieckbesser ist:
Figur | AbstractDreieck / \ Dreieck gleichseitigesDreieckAbstractDreieck stellt dabei nur das gemeinsame Interface dar.
-
camper schrieb:
Weil ein Konstruktor immer alle nichtstatischen Member (und dazu zählen mögliche Basisklasse) initialisiert, wenn diese keine PODs sind. PODs werden nur initialisiert, wenn sie explizit in der Initialisierungsliste auftauchen.
Deine Verwirrung ist nicht ganz unberechtigt, allerdings liegt das Problem an anderer Stelle. Ein (Objekt des Typs) gleichseitigesDreieck ist kein Dreieck. Generell (99:1) ist es ein Fehler, von konkreten Klassen (solche, die selbst vollständige Objekte erstellen) öffentlich abzuleiten.
Ja ein design fehler ist es alle mal, aber die Aufgabenstellung verlangt es nunmal das man von einem Rechteck ein Quadrat ableiten soll. Oder von Dreieck einen Gleichseitigen und Gleichschenkligen ableiten müsse. Deswegen kommen mir auch solche Fragen hoch. Aber immer positiv sehen aus fehlern anderer lern man auch.

-
camper schrieb:
Weil ein Konstruktor immer alle nichtstatischen Member (und dazu zählen mögliche Basisklasse) initialisiert, wenn diese keine PODs sind. PODs werden nur initialisiert, wenn sie explizit in der Initialisierungsliste auftauchen.
Sorry POD ???
-
camper schrieb:
...PODs werden nur initialisiert, wenn sie explizit in der Initialisierungsliste auftauchen....

Echt ?struct A { int a, b; A() : a(1), b(2) {} }; struct B : A { }; int main() { B b;Wird hier nicht A::A() aufgerufen ?
Oder ist A kein POD ?Gruß,
Simon2.
-
Du wartest jetzt zwar sicher auf camper,
aber:
Eine struct mit Konstruktor ist kein POD mehr
@Dima
POD (Plain old data).
-
Dima schrieb:
Das sieht irgenwie getrickst aus. Gibt es keine andere möglichkeit?
Den das Dreieck(x, y) benötig man ja gar net. Denn die Variablen von Dreieck will ich nicht benutzen.Du hast hierbei ein Deckproblem, hierzu rollen wir mal alles auf (Nur bezogen auf den Regelfall, nicht auf solche Spezialitäten wir private Ableitungen...):
Ja, umgangssprachlich kann man sagen das ein gleichseitigesDreieck ein Dreieck ist. Vererbung setzt man ein um Anzuzeigen, das es sich um ein spezialisiertere Form handelt, nicht aber für Einschränkungen. Alles was die Basisklasse als Schnittstelle unterstützt muss auch die abgeleitete Klasse unterstüzen. Die abgeleitete Klasse "ist ein" auch ein Element der Basisklasse.
Einschränkungen stellt man besser durch Eigenschaften dar, als durch Ableitungen. Ich schätze mal du wirst es an einen extremen Beispiel verstehen:
class Dreieck; class BlauesDreieck : public Dreieck;Ich hoffe mal dir leuchtet ein, das sowas nicht sinnvoll ist.
So, da eine Abgeleitete Klasse nun alles was die Basisklassen repräsentieren auch darstellt, muss es auch alles initialisieren was dazu gehört. Dazu müssen passende Konstruktoren der Basisklasse aufgerufen werden. Falls es kein Standardkonstruktor gibt, musst du einen spezialisierten in der Initialisieungsliste aufrufen.
Was aber grundsätzlich geht: Du kannst einen Konstruktor auch protected deklarieren, so das er von Außerhalb nicht zugreifbar ist. Aber auch das verbessert kein schlechtes Design.
Und zu guter letzt: Vererbung lässt sich auch durch Komposition ersetzen. Bei Komposition enthält deine Klasse eine andere, gibt aber nur seine Schnittstelle frei. Du könntest z.B. sagen du schreibst eine Klasse gleichseitigesDreieck, da aber die Regeln für ein Dreieck nicht vollständig zutreffen leitest du nicht ab, sondern schreibst eine passende Schnittstelle. Bei der Implementierung kannst du aber auf das Dreieck zurückgreifen, und nimmst daher ein Dreieck als Member.
Noch immer kein wirklich gutes Design, aber besser als die Vererbung.
cu André
-
Dima schrieb:
Ja ein design fehler ist es alle mal, aber die Aufgabenstellung verlangt es nunmal das man von einem Rechteck ein Quadrat ableiten soll. Oder von Dreieck einen Gleichseitigen und Gleichschenkligen ableiten müsse. Deswegen kommen mir auch solche Fragen hoch. Aber immer positiv sehen aus fehlern anderer lern man auch.

Vermutlich kommt die "Auflösung" nach der Aufgabenstellung, mit einer Erklärung warum es schlechtes Design ist ;p
-
asc schrieb:
Ableitungen. Ich schätze mal du wirst es an einen extremen Beispiel verstehen:
class Dreieck; class BlauesDreieck : public Dreieck;Ich hoffe mal dir leuchtet ein, das sowas nicht sinnvoll ist.
Nee, das leutet mir jetzt nicht ein.
Ein BlauesDreieck kann ja im prinzip alles von der Basisklasse erben immerhin ist es ja ein dreieck, bloß das es blau ist. Also eine Eigenschaft z.B. Farbe mehr hat. also könnte man doch die Eigenschaften und Methoden von dem Dreieck erben? Oder nicht?Und zu guter letzt: Vererbung lässt sich auch durch Komposition ersetzen. Bei Komposition enthält deine Klasse eine andere, gibt aber nur seine Schnittstelle frei. Du könntest z.B. sagen du schreibst eine Klasse gleichseitigesDreieck, da aber die Regeln für ein Dreieck nicht vollständig zutreffen leitest du nicht ab, sondern schreibst eine passende Schnittstelle. Bei der Implementierung kannst du aber auf das Dreieck zurückgreifen, und nimmst daher ein Dreieck als Member.
Noch immer kein wirklich gutes Design, aber besser als die Vererbung.
[/quote]
Wie sieht den so eine komposition aus?
evtl. C++ Code? Bin eher praktisch orientiert
-
Dima schrieb:
Nee, das leutet mir jetzt nicht ein.
Okay, einleuchten wird es dir spätestens wenn du dies für alle Webfarben einmal machen darfst ;)... Es gibt Dinge die drückt man durch Eigenschaften, nicht vererbung aus. Und ob ein Dreieck nun gleichseitig ist oder nicht, ist eher eine Eigenschaft als eine eigenständige Einheit.
Dima schrieb:
Wie sieht den so eine komposition aus?
evtl. C++ Code? Bin eher praktisch orientiert
class gleichseitigesDreieck { private: Dreieck dreieck; //... public: //... };cu André
-
Braunstein schrieb:
...
Eine struct mit Konstruktor ist kein POD mehr
...Aha !! Ich dachte es würde ein trivialer Destruktor reichen. Danke - man lernt nie aus.
Braunstein schrieb:
Du wartest jetzt zwar sicher auf camper,
...Ach neee, Dir glaube ich auch (fast) alles

Gruß,
Simon2.
-
FAQ, ganz Oben. Ist bewusst kurz gehalten, um das Nachschlagen zu erleichtern, als Einführung ist es viel zu knapp.
-
Vererbung wird meistens immer als "ist ein" ... in diesen komischen beziehungskisten in diversen veranschauligungsmodellen ausgedrueckt. Was aber ungluecklich und eher irritierend ist ^^
vererbung = kann benutzt werden wie ein ...
Kannst du ein blaues dreick benutzen wie ein normales dreieck ? nicht wenn man am normalen dreieck die farbe einstellen kann ...
Du versuchst auch vererbung volkommen falsch zu verwenden. Aber genau den selber fehler machen viele andere Einsteiger auch

Vererbung sollte man niemals benutzen, um simpel code wiederverwenden. Dazu ist Aggregation, oder die staerke variante, die komposition da, wie oben schon erlaeutert.
Vererbung sollst du nutzen, wenn du unterschiedliche Objecte gleich behandeln willst und durch den Objecttyp das verhaltewn steuern willst.
Objecte zur laufzeit "austauschen", das ist die philosophie von vererbung, nicht funktionalitaet durchzuschleifen ....
Ciao ...