Warum keine Vererbung von operator=
-
camper schrieb:
...Was die Signatur hier zu suchen hat, bleibt schleierhaft....
Hmmmm, einmal versuche ich's noch.
Was üblicherweise von einer "geerbten Funktion" erwartet, ist folgendes:struct A { void f(int); }; struct B: public A { void g(string); }; int main() { A a; a.f(3); // (*) B b; b.f(3); // geht und macht dasselbe wie (*) ...Sprich: "Wenn die Basisklasse das kann, kann es auch die Kindklasse"
So wird (meine Vermutung) auch hier die Erwartung gewesen sein: "Wenn bereits die Basisklasse kopierbar ist, dann auch die Kindklassen".
Im Gegensatz zu obigem Beispiel gibt es aber IMMER einen operator=(), der
- den der Basisklasse verdeckt UND
- eine andere Signatur hat (im Gegensatz zu f()).Aber wie Du schon gesagt hast: Ist alles OT und ich bin immer noch nicht davon überzeugt, dass ich Quatsch geschrieben habe.
Gruß,
Simon2.
-
Der Knackpunkt ist das Verdecken. Um es mit deinem Beispiel zu sagen: dein struct B hat in dem Fall immer ein void f(float) (oder string oder sogar int), entweder explizit angegeben oder implizit vom Compiler hinzugefuegt. Die Deklaration einer Funktion gleichen Namens verdeckt unabhaengig von der Signatur die Fanktion der Basisklasse, weshalb die unterschiedliche Signatur irrelevant ist.
struct A { A& operator= (const A&); }; struct B : A { A& operator= (const A&); //Aeusserst ungewoehnlich, aber machbar };Trotz der gleichen Signatur ueberdeckt hier op= den geerbten op=. Und es ist egal, ob das Ding nu op= oder f() oder schlagmichtot() heisst. Der einzige unterschied zu "normalen" Methoden ist der, dass op= vom Compiler eine implizite Deklaration verpasst bekommt fuer die Klassen, die ihn nicht explizit deklarieren, in welcher Form auch immer.
-
struct Bar; struct Foo { Bar& operator=(const Bar&); // gleiche Signatur wie Copy-Zuweisungsoperator in Bar Foo& operator=(const Foo&); }; struct Bar { using Foo::operator=; };Bar hat jetzt die Zuweisungsoperatoren
Bar& Bar::operator=(const Bar&) (implizit deklariert und verdeckt immer noch den operator gleicher Signatur in Foo)
Foo& Bar::operator=(const Foo&) (aus Foo, eigentlich verdeckt, durch using sichtbar gemacht)Die Verdeckung des Operators gleicher Signatur aus der Basisklasse ist hier allerdings eine Spezialregel der using-Deklaration - die allgemeine Regel würde Mehrdeutigkeit implizieren (dann hätte die Klasse aber gar keinen Kopierzuweisungsoperator - das darf nicht sein) oder die Verhinderung der impliziten Deklaration.
Simon2s Standpunkt ist durchaus haltbar - ich bestreite nur, das meine Argumentation widersprüchlich ist.
-
oehm Moment. Wer erbt hier von wem? In diesem beispiel gibts garkeine Vererbung und daher wird auch kein geerbter op= verdeckt. So wie es hier steht hast du zwei unabhaengige Klassen die beide die zwei gleichen Zuweisungsopis haben - wobei ich bezweifle dass das das so kompiliert, zumindest nicht, wenn du irgendwelche Member hast die du in den op= bearbeitest.
-
camper schrieb:
...ich bestreite nur, das meine Argumentation widersprüchlich ist.

Ach sooooo - das war wohl nur ein Mißverständnis: Ich meinte nicht, dass DEINE Argumentation widersprüchlich sei, sondern hustbaers Aussage "geerbte Funktionen kann man nicht überladen" (die er natürlich auch nicht in der Allgemeinheit meinte) relativieren wollen !
Dafür habe ich Deine Aussage benutzt.Sorry, dass ich das in dem Zusammenhang nicht klar genug rausgestellt habe.
Gruß,
Simon2.
-
pumuckl schrieb:
oehm Moment. Wer erbt hier von wem? ...
Naja, das ist doch wohl eher ein schnell identifizierter Typo. Gemeint ist bestimmt:
struct Bar; struct Foo { // ... }; struct Bar : Foo { // ..Würde ich jetzt jedenfalls aus dem Zusammenhang (und der Namensgebung) schließen.
pumuckl schrieb:
...
struct A { A& operator= (const A&); }; struct B : A { A& operator= (const A&); //Aeusserst ungewoehnlich, aber machbar };...
Trotzdem bekommt (IIRC) B hier noch einen operator=(const B&) verpasst, dessen Signatur "nicht passt".
Aber nun hängt Euch doch nicht so an meiner Randbemerkung auf !!

Ich habe NIEEEMALS behauptet, dass die Verdeckung unwichtig, sondern nur, dass es selbst dann nicht funktionieren würde, wenn die C++-Designer das mit der Verdeckung anders geregelt hätten.
Den fachlichen Grund dafür hat Jaxom bereits in seinem ersten Posting genannt ("...es würden nur Basisklassenanteile kopiert, es würden Redundanzen entstehen usw...."); worin sich das technisch/semantisch ausdrückt, wollte ich mit dem Hinweis auf die Signatur unterstreichen - mehr nicht.Gruß,
Simon2.
-
Simon2 schrieb:
pumuckl schrieb:
oehm Moment. Wer erbt hier von wem? ...
Naja, das ist doch wohl eher ein schnell identifizierter Typo. Gemeint ist bestimmt:
struct Bar; struct Foo { // ... }; struct Bar : Foo { // ..Jo, das wars. danke.
-
camper schrieb:
...Jo, das wars. danke.
Gern geschehen !

-
@Simon2:
Ich verstehe immer noch nicht wie du geerbte Funktionen überladen willst.
Überladen heisst für mich dass beim Aufruf auch "overload resolution" gemacht wird, und wenn ich durch den vermeintlichen "Overload" alle gleichnamigen Funktionen der Basisklasse verdecke, dann passiert eben keine "overload resolution" mehr wenn ich unqualifiziert aufrufe. Und wenn ich mit der Basisklasse qualifiziere ... dann wird der neue "Overload" in der abgeleiteten Klasse auch nicht verwendet.Also. Wie überlade ich geerbte Funktionen?
-
hustbaer schrieb:
Also. Wie überlade ich geerbte Funktionen?
Indem ich sie per using in den Scope der abgeleiteten Klasse ziehe und dann überlade

-
-
CStoll schrieb:
hustbaer schrieb:
Also. Wie überlade ich geerbte Funktionen?
Indem ich sie per using in den Scope der abgeleiteten Klasse ziehe und dann überlade

using gilt nicht, das ist geschummelt
