Virtuelle Funktion wird verdeckt!



  • @volkard:
    Ich glaube, du bist zu streng. Dein operator verlangt zwei Base und sollte sich meiner Meinung nach nicht darum scheren, ob seine Argumente "in Wirklichkeit" Unterklassen sind. Die Funktion sollte true liefern, wenn die Base-Anteile der Objekte gleich sind und Schluß.

    Ich gebe zu, daß es mir schwer fällt zu erklären, warum ich dieser Meinung bin. Im Moment fühlt sich das einfach nur richtig an.

    Vielleicht könnte man so sagen: Die Umgebung, in der dieser Vergleich stattfindet, wird wohl eine Base-Umgebung sein. Wenn Base Unterklassen hat, gibt es diese Base Umgebung als eine Art Framework für alles, was man mit Base machen kann. Ich unterstelle, daß dieses Framework per Design so geschaffen ist. Ein Test auf Gleichheit zweier Base _muß_ dann true liefern, falls der Base-Anteil der Objekte gleich ist, denn ich glaube, daß ein solches Framework anders gar nicht (richtig) funktionieren kann. Ein Test auf den _Wert_ eines Objekts sollte nicht vom _Typ_ des Objekts abhängen. Mit ist so, als würde ansonsten der Polymorphismus seine Unschuld verlieren.

    Ich habe bisher noch nie mit virtuellen operator==() experimentiert. Vielleicht ist dieser Beitrag deshalb ein bischen schwammig......

    Stefan.



  • Das würde ja bedeuten, dass ein Hund gleich einem Pinguin ist, wenn sie gleich alt sind?



  • Das würde ja bedeuten, dass ein Hund gleich einem Pinguin ist, wenn sie gleich alt sind?

    Nein, das würde bedeuten, daß zwei _Tiere_ gleich sind, wenn sie gleich alt sind. Und das unabhängig davon, ob es nun Hunde oder Pinguine sind. Das habe ich mit diesem Begriff "Framework für Base" gemeint. Im Kontext des operator==(const Tier&, const Tier&) gibt es weder Hunde noch Pinguine, bloß Tiere.

    Stefan.



  • Fazit:
    Die Implementierung ist Kontexabhängig.



  • Scheiss neues Forum, immer wieder ausgeloggt. 😡



  • Ich hab dich schon verstanden, ich finde es nur sinnlos, dass du dem Vergleichsoperator willkürlich einen solchen eingeschränkten Kontext geben willst.

    Hund h("Collie", 42);
    Pinguin p(42);
    assert(h == p);
    

    finde ich fragwürdig.



  • Hund h("Collie", 42);
    Pinguin p(42);
    assert(h == p);

    C/C++ Code:
    .........

    finde ich fragwürdig.

    Sehe ich genau so.



  • Es kommt auf den Zusammenhang an. Die Frage kann man nicht mit Hunden und Pinguinen klären. Es wär doch möglich, dass man einmal einen Fall hat wo es Sinn macht.



  • Eine goldene Regel in C++ ist, das Operatoren genau das tun sollten, was von ihnen erwarte wird. Dieses gilt dann natürlich auch für den operator == (). Soll dieses weiterhin als Regel gelten, ergeben sich daraus einige Konsequenzen.

    Als erste Möglichkeit definieren wir mal den operator == () nur für eine Basisklasse und nicht für die abgeleiteten Klassen. Ich vergleich z.B. zwei Tiere - wenn sie gleich alt sind gibt es ein true. Das hätte zur folge, das wenn ich ein Pinguin und einen gleich alten Waschbären vergleichen würde, diese auch gleich wären (wie unten schon beschrieben) => Als Außenstehender würde ich das nicht erwarten. Also sollte man das vermeiden. Als Lösung für eventuell doch notwendige Vergleiche kann mann immer noch explizite Vergleichsfunktionen definieren. Den Algorithmen der STL kann man fast immer soch einen Vergleich explizit angeben.

    Die zweite Möglichkeit ist dann der virtuelle operator == (), der überschrieben wird. Hier wäre es ohne weiteres zunächst möglich, ob das übergebene Objekt vom gleichen Typ wie das erste Argument ist (RTTI -> wie unten beschrieben). Danach kann eine Typenumwandlung (gefahrlos) erfolgen und ein tiefgehender Vergleich angestellt werden. In diesem Fall ist das Verhalten auf jeden Fall erwartet. Es gibt nur ein true zurück, wenn es sich tatsächlich um Gleichheit handelt (wenn die Implementierung auch soweit in Ordnung ist).

    Dann ergibt sich noch die Frage nach dem Sinn eines virtuellen operators == (). Ein Einsatzbeispiel wären (oder besser sind) virtuelle Iteratoren. Will man zwei virtuelle Iteratoren Vergleichen, so muß das tatsächliche Typ auch übereinstimmen. Für Iteratoren ist der operaror == () außerdem zimlich wichtig, wenn man sie standardmäßig benutzen will.

    Übrigens ist der Einsatz von RTTI in diesem Fall zimlich ungefärlich. Es wird nur einmal der Typ abgefragt. RTTI führt hier nicht zu switch-konstrukten und deren Problemen.



  • @Bashar:
    Dein Beispiel ist für mich genauso fragwürdig wie für dich. Allerdings trifft es (*hüstel*) nicht das Problem, um das es hier geht.

    Der springende Punkt ist doch (so habe ich das zumindest verstanden), daß operator==() für Oberklassen (also z.B. für Tier) aufgerufen wird. Und durch die Beispiele wurde zumindest implizit klar, daß alle Klassen dieser Hierarchie einen operator==() implementieren. Unter diesen Voraussetzungen schlägt deine Assertion fehl - und das sollte sie auch.

    Stefan.


Anmelden zum Antworten