Problem mit abstrakter Methode
-
hustbaer schrieb:
...
Und vermutlich weil die Sache so verflixt danach aussieht als ob hier "isEqual(SuperClass* s)" statt "isEqual(SuperClass s)" gemeint war dann die Frage ob du vorher Java programmiert hast (weil dort die Schreibweise "isEqual(SuperClass s)" korrekt wäre).Eben.

-
Servus,
danke für eure zahlreichen Antworten. Tatsächlich komme ich ursprünglich aus der Java-Welt. So etwas wie Operatorenüberladung ist mir neu, aber im Grunde das, was ich in diesem Zusammenhang suche.
Ich würde nur gern irgendwie erzwingen, dass der Vergleichsoperator von abgeleiteten Klassen überladen wird.
Ich nehme an, auchvirtual bool operator ==(SuperClass s) = 0;bzw.
virtual bool operator ==(SuperClass* pS) = 0;wird aus den genannten Gründen nicht funktionieren.
Nochmal zur Erklärung, was ich eigentlich modellieren will:
Ich habe eine Schnittstellenklasse "ParameterSet", welche unter anderem die Methoden "virtual void setStandardParameter() = 0;" und "virtual int getChecksum() = 0;" vorgibt, die abgeleitete Klassen implementieren müssen. Hier würde ich auch gern eine (virtuelle) Vergleichsoperation unterbringen.
Vielleicht habt ihr eine Idee.Gruß, Tim.
-
Wenn du deiner Superklasse eine abstrakte Vergleichsfunktion mit sich selbst definierst, dann bedeutet das, dass alle abgeleiteten Klassen auch eine Vergleichsfunktion mit der Superklasse haben müssen. Wenn du also von der Superklasse zwei Klassen Konkret1 und Konkret2 ableitest, müssen die beiden auch untereinander vergleichbar sein. In den meisten Fällen ist das Unsinn...
-
Ok, das verstehe ich soweit.
D.h. es ist grundsätzlich nicht möglich, eine Schnittstellenfunktion zu definieren, in deren Argumenten ein Bezug zur abgeleiteten Klasse hergestellt wird?
-
Tim_ schrieb:
Ok, das verstehe ich soweit.
D.h. es ist grundsätzlich nicht möglich, eine Schnittstellenfunktion zu definieren, in deren Argumenten ein Bezug zur abgeleiteten Klasse hergestellt wird?Ein klares JEIN
Schau dir mal folgendes an:class AbstractSuperClass { public: virtual void setStandardParameter() = 0; virtual int getChecksum() = 0; }; template <class Derived> class SpecificSuperClass : public AbstractSuperClass { public: virtual bool isEqual(Derived const& other) = 0; }; class Concreteclass : public SpecificSuperClass<Concreteclass> { public: //hier muss isEqual(Concreteclass const&) definiert werden };Die Art, aus der Basisklasse ein template zu machen das abhängig ist von der abgeleiteten Klasse, nennt sich "Curiously Recurring Template Pattern" - für mehr Informationen darüber gibts bei google vermutlich ne Menge Links.
-
pumuckl, wenn ich das richtig verstehe, erzwingt das nur, dass ConcreteClass die Funktion "bool isEqual( ConcreteClass const& )" implementieren muss? Welchen Vorteil hat das gegenüber dem, dass man ConcreteClass direkt von AbstractSuperClass ableitet und die Methode isEqual "einfach so" implementiert?
-
pumuckl schrieb:
Ein klares JEIN
Schau dir mal folgendes an:class AbstractSuperClass { public: virtual void setStandardParameter() = 0; virtual int getChecksum() = 0; }; template <class Derived> class SpecificSuperClass : public AbstractSuperClass { public: virtual bool isEqual(Derived const& other) = 0; }; class Concreteclass : public SpecificSuperClass<Concreteclass> { public: //hier muss isEqual(Concreteclass const&) definiert werden };Ok, mit virtuellen Template-Methoden hatte ich schon erfolglos experimentiert aber das Template über die ganze Klasse zu setzen, ist mir bisher noch nicht in den Sinn gekommen.

Danke für den Tipp.
-
Also ich verstehe wiedermal den ganzen Aufstand hier nicht.
isEqual ist schon OK als Funktionsname, und es ist auch OK das in der Basisklasse anzusiedeln:class Object { public: virtual bool isEqual(Object const* other) const = 0; };Das hat den Vorteil dass man 2 "Objekte" vergleichen kann, auch ohne zu wissen ob sie überhaupt vom gleichen Typ sind. D.h. ich kann einen String mit einem Rechteck vergleichen (und würde einfach nur "false" rausbekommen).
Was oft sehr praktisch ist.
Oder ich kann rausbekommen dass 2 Objekte gleich sind, ohne wissen zu müssen von welchem Typ sie nun sind.
-
hustbaer schrieb:
Das hat den Vorteil dass man 2 "Objekte" vergleichen kann, auch ohne zu wissen ob sie überhaupt vom gleichen Typ sind. D.h. ich kann einen String mit einem Rechteck vergleichen (und würde einfach nur "false" rausbekommen).
Was oft sehr praktisch ist.Wann ist das praktisch?
Sicher, in gewissen Vererbungshierarchien mag ein solches Wissen notwendig sein (Composite Pattern …). Aber ich sehe keine Situation, in der man Strings mit Rechtecken vergleichen muss.
-
hustbaer schrieb:
...ich kann einen String mit einem Rechteck vergleichen (und würde einfach nur "false" rausbekommen)...
Nicht unbedingt ... das hängt doch ziemlich von der Art des Vergleichs ab.
Gruß,
Simon2.
-
Konrad Rudolph schrieb:
/EDIT: Hmm, die Syntax ist so wohl doch nicht ganz vollständig. Keine Ahnung, wie man das genau machen müsste. Hab das erst sehr selten verwendet.
Bevor ich mich geschlagen gebe, würde ich trotz allem gerne noch wissen, wie das aussehen soll. Die ? extends foo Syntax hab ich bisher nur im Kontext von Generics gesehen, und ich bin mir nicht ganz sicher ob das das ist was wir hier suchen.
-
Bashar schrieb:
Konrad Rudolph schrieb:
/EDIT: Hmm, die Syntax ist so wohl doch nicht ganz vollständig. Keine Ahnung, wie man das genau machen müsste. Hab das erst sehr selten verwendet.
Bevor ich mich geschlagen gebe, würde ich trotz allem gerne noch wissen, wie das aussehen soll. Die ? extends foo Syntax hab ich bisher nur im Kontext von Generics gesehen, und ich bin mir nicht ganz sicher ob das das ist was wir hier suchen.
Ja, ich meinte es auch durchaus im Kontext von Generics. Wobei man hierfür die Template-Kontravarianz gar nicht braucht (hmm, fällt mir spät ein) – ich meinte eigentlich so etwas wie CRTP für Java, womit der erzielte Effekt erreicht würde. … bin gerade ein wenig konfus.
(Ich habe keine Ahnung, ob man sowas in Java überhaupt verwendet, aber in .NET macht man das.)
abstract class Base<T> { public abstract boolean isEqual(T other); } class Derived extends Base<Derived> { public boolean isEqual(Derived other) { return true; } };