virtueller Zuweisungsoperator C ++
Zuweisungsoperator in C++ vorgenommen werden können virtuellen. Warum ist es erforderlich? Können wir machen, anderen Betreibern von virtuellen zu?
InformationsquelleAutor der Frage Kazoom | 2009-03-21
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den Zuweisungs-operator ist nicht verpflichtet, die virtuellen.
Die Diskussion unten über
operator=
, aber es gilt auch zu jedem operator überladen, dass dauert in der Art in Frage, und jede Funktion, die dauert in der Art in Frage stellen.Den unten Diskussion zeigt, dass das Schlüsselwort virtual nicht weiß, über einen parameter die erbschaft im Hinblick auf das finden einer passenden Funktion Unterschrift. In das Letzte Beispiel zeigt, wie man richtig zu behandeln Zuordnung beim Umgang mit ererbten Typen.
Virtuelle Funktionen wissen nichts über das parameter-Vererbung:
Eine Funktion ist, die Unterschrift muss identisch sein für virtuelle ins Spiel kommen. Obwohl also im folgenden Beispiel, operator= ist aus virtuellen, der Anruf wird nie handeln als virtuelle Funktion in D, da die Parameter und der Rückgabewert von operator= sind anders.
Die Funktion
B::operator=(const B& right)
undD::operator=(const D& right)
sind zu 100% komplett anders und gesehen wie 2 verschiedene Funktionen.Default-Werte und mit 2 überladen von Operatoren:
Können Sie zwar definieren, die eine virtuelle Funktion, um Ihnen zu erlauben, um die Standardwerte für D, wenn es zugeordnet ist variable vom Typ B. Dies gilt auch, wenn deine variable B ist wirklich ein D gespeichert, in eine Referenz zu einem B. werden Sie nicht bekommen, die
D::operator=(const D& right)
Funktion.In der unten Fall eine Zuordnung von 2-D-Objekte gespeichert, die auf der Innenseite 2 B Referenzen... die
D::operator=(const B& right)
überschreiben verwendet wird.Drucke:
Was zeigt, dass
D::operator=(const D& right)
ist nie benutzt.Ohne das Schlüsselwort virtual auf
B::operator=(const B& right)
Sie würden die gleichen Ergebnisse wie oben, aber der Wert von y würde nicht initialisiert werden. I. e. würde es dieB::operator=(const B& right)
Einen letzten Schritt binden Sie es alle zusammen, RTTI:
Können Sie RTTI richtig zu handhaben, virtuelle Funktionen, die in Ihrem Typ. Hier ist das Letzte Stück des Puzzles, um herauszufinden, wie man richtig zu behandeln Zuordnung beim Umgang mit möglicherweise vererbten Typen.
InformationsquelleAutor der Antwort Brian R. Bondy
Kommt es auf den Betreiber.
Dem Punkt, an dem ein Zuweisungsoperator virtual ist, damit Sie vom nutzen des seins in der Lage, um es zu überschreiben, zu kopieren Feldern.
Also, wenn Sie eine Base& und Sie haben tatsächlich eine Abgeleitete und als dynamischer Art, sowie die daraus Abgeleitete hat mehr Felder, die richtigen Dinge werden kopiert.
Es besteht dann allerdings die Gefahr, dass Ihre LHS ist eine Abgeleitete, und die RHS ist eine Basis, so dass, wenn der virtuelle Bediener läuft in Abgeleiteten Parameters ist nicht Abgeleitet und Sie haben keine Chance, Felder, draus.
Hier ist eine gute discussio:
http://icu-project.org/docs/papers/cpp_report/the_assignment_operator_revisited.html
InformationsquelleAutor der Antwort Uri
Möchte ich hinzufügen, zu dieser Lösung ein paar Bemerkungen. Mit dem Zuweisungsoperator deklariert ist die gleiche wie oben, hat drei Probleme.
Generiert der compiler eine Zuweisung ein operator ist, der nimmt ein const D& argument, das ist nicht virtuell und nicht tun, was Sie vielleicht denken, es tut.
Zweite Problem ist der return-Typ, sind Sie wieder ein Basis-Referenz auf eine abgeleitete Instanz. Wahrscheinlich nicht viel von einem Problem, wie der code funktioniert trotzdem. Noch besser ist es, die Referenzen zurückgeben entsprechend.
Dritten Ausgabe abgeleiteten Typ Zuweisungsoperator nicht nennen Basisklasse Zuweisungsoperator (was ist, wenn es private Felder, die Sie kopieren möchten?), deklarieren den Zuweisungsoperator als virtuelle nicht die compiler generieren für Sie. Dies ist eher ein Nebeneffekt, der nicht mit mindestens zwei überladungen der Zuweisungsoperator, um die erwünschten Ergebnis.
Unter Berücksichtigung der Basis-Klasse (die gleiche wie die von der post den ich zitiert):
Folgende code schließt die RTTI-Lösung, die ich zitiert:
Mag es scheinen, eine vollständige Lösung ist es nicht. Dies ist keine vollständige Lösung, weil wenn Sie die Ableitung von D benötigen Sie 1 operator = , dauert const B&, 1 operator = , dauert const D& und einem operator, der nimmt const D2&. Die Schlussfolgerung liegt auf der Hand, die Anzahl von operator = () - überladungen ist gleichbedeutend mit der Anzahl der super-Klassen + 1.
Wenn man bedenkt, dass D2 D erbt, lassen Sie uns nehmen einen Blick an, wie die beiden geerbten operator =() Methoden Aussehen.
Es ist offensichtlich, dass die operator =(const D2&) nur Kopien Felder, stellen Sie sich vor, als ob es dort war. Wir können feststellen, ein Muster in den geerbten operator = () - überladungen. Leider können wir uns nicht definieren, virtuelle Vorlage Methoden, kümmert sich um dieses Muster, wir brauchen Sie zum kopieren und einfügen mehrere Male den gleichen code, um eine vollständige polymorphe Zuweisung-operator die einzige Lösung, die ich sehe. Gilt auch für die anderen binären Operatoren.
Bearbeiten
Wie bereits erwähnt in den Kommentaren, das Mindeste, was getan werden kann, um das Leben leichter machen, ist die Festlegung der obersten Superklasse Zuweisungs-operator =(), und rufen Sie es von allen anderen Oberklasse-operator = () - Methoden. Auch beim kopieren von Feldern eine _copy-Methode definiert werden kann.
Gibt es keine Notwendigkeit für eine set defaults Methode, denn Sie würde erhalten, nur einen Anruf (in der Basis-operator =() überladen). Änderungen beim kopieren von Feldern sind an einem Ort durchgeführt werden und alle operator = () - überladungen sind betroffen und tragen den beabsichtigten Zweck.
Dank sehe für die Anregung.
InformationsquelleAutor der Antwort Andrei15193
virtuelle Zuweisung wird verwendet in folgenden Szenarien:
In diesem virtuellen Konzept nicht eine Rolle spielen, wie wir Sie nennen
operator=
aufChild
Klasse.Hier die Zuweisung nicht wie erwartet. Grund dafür ist
operator=
heißt aufBase
Klasse statt.Er kann korrigiert werden, entweder:
1) Casting
2) Virtuelle Konzept
Nun einfach mit
virtual Base& operator=(const Base& obj)
wird nicht helfen, wie Signaturen unterscheiden sich inChild
undBase
füroperator=
.Müssen wir hinzufügen
Base& operator=(const Base& obj)
in der Kind-Klasse zusammen mit seinen üblichenChild& operator=(const Child& obj)
definition. Seine wichtig, später definition, wie in der Abwesenheit des default-Zuweisungsoperator aufgerufen werden.(obj1=obj2
möglicherweise nicht gewünschte Resultat)In diesem Fall compiler sucht
operator=(Base& obj)
definition inChild
alsoperator=
genannt wird auf Kind. Aber seit der nicht anwesend ist, undBase
Typ kann nicht gefördert werden, umchild
implizit, es wird durch Fehler.(casting erforderlich ist, wieobj1=dynamic_cast<Child&>(*ptr1);
)Führen wir nach case2&3, dieses Szenario wird gesorgt sein.
, Wie es gesehen werden kann, virtuelle Zuordnung macht call eleganter in-bei Aufträgen mit Base class Pointer/Referenz .
InformationsquelleAutor der Antwort sorv3235055
Es ist nur erforderlich, wenn Sie sicherstellen wollen, dass Klassen, die von Ihrer Klasse bekommen alle Ihre Mitglieder korrekt kopiert. Wenn Sie nicht tun, alles, was mit Polymorphismus, dann müssen Sie nicht wirklich brauchen, zu kümmern.
Ich kenne nichts, dass würde verhindern, dass Sie durch die Virtualisierung jeder operator, den Sie wollen-Sie sind nichts als der Besondere Fall-Methode aufruft.
Auf dieser Seite bietet eine sehr gute und ausführliche Beschreibung, wie dies alles funktioniert.
InformationsquelleAutor der Antwort sblom
Ein operator ist eine Methode mit einer speziellen syntax. Sie können Sie behandeln wie jede andere Methode...
InformationsquelleAutor der Antwort dmckee