Überschreiben von öffentlichen virtuellen Funktionen mit privaten Funktionen in C ++
Ist, es gibt keinen Grund, um die Berechtigungen für eine überschriebene virtuelle C++ - Funktion unterscheidet sich von der Basisklasse? Besteht irgendeine Gefahr dabei?
Beispiel:
class base {
public:
virtual int foo(double) = 0;
}
class child : public base {
private:
virtual int foo(double);
}
Den C++ - faq sagt, dass es eine schlechte Idee ist, aber nicht sagen, warum.
Habe ich gesehen, dass dieses idiom in einigen code, und ich glaube, dass der Autor versucht hat, um die Klasse final, basierend auf der Annahme, dass es nicht möglich ist, zu überschreiben, eine private member-Funktion. Allerdings Dieser Artikel zeigt ein Beispiel des überwiegenden privaten Funktionen. Natürlich ein weiterer Teil der C++ - faq abgeraten, dies zu tun.
Meine konkreten Fragen:
- Ist es ein technisches problem mit einer anderen Berechtigung für virtuelle Methoden in abgeleiteten Klassen vs Basisklasse?
- Ist es eine legitime Grund, dies zu tun?
InformationsquelleAutor der Frage Ben Martin | 2009-01-27
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das problem ist, dass die Basisklasse die Methoden sind die Art und Weise der Deklaration seiner Schnittstelle. Es ist in der Essenz zu sagen, "Dies sind die Dinge, die Sie tun können, um Objekte dieser Klasse."
Wenn in einer Abgeleiteten Klasse, die Sie machen, etwas die Basis der erklärt hatte, wie öffentlich-private, Sie nehmen etwas Weg. Nun, auch wenn ein Abgeleitetes Objekt "ist-ein" Basis-Objekt, etwas, dass Sie sollten in der Lage sein zu tun, um ein Basis-Objekt-Klasse können Sie tun, um ein Objekt Abgeleitete Klasse, brechen die Liskov Substitution Prinicple
Wird dadurch ein "technisches" problem in Ihrem Programm? Vielleicht auch nicht. Aber es wird wahrscheinlich bedeuten, ein Objekt der Klassen nicht in einer Weise benehmen, die Ihre Benutzer erwarten, dass Sie sich zu benehmen.
Wenn Sie sich in der situation, wo das ist, was Sie wollen (außer im Fall einer veralteten Methode bezeichnet, die in einer anderen Antwort), die Chancen sind Sie haben ein Erbe-Modell, in denen die Vererbung nicht wirklich modeling "ist-ein" (z.B. Scott Myers ' s z.B. Quadrat erbt von Rechteck, aber Sie können nicht ändern, ein Quadrat, dessen Breite unabhängig von Ihrer Höhe, wie Sie für ein Rechteck), und möglicherweise müssen Sie überdenken Ihre Klasse Beziehungen.
InformationsquelleAutor der Antwort JohnMcG
Bekommen Sie das überraschende Ergebnis, dass, wenn Sie ein Kind haben, können Sie nicht anrufen, foo, aber Sie warf ihn auf einen sockel zu stellen und dann Aufruf von foo.
Ich nehme an, Sie könnten in der Lage sein, zu verstehen ein Beispiel, wo Sie nicht möchten, dass eine Funktion ausgesetzt, es sei denn, Sie behandeln Sie es als eine Instanz der Basis-Klasse. Aber die Tatsache, dass diese situation erscheint würde vorschlagen, ein schlechtes OO-design, die irgendwo entlang der Linie, die sollte wohl umgestaltet werden.
InformationsquelleAutor der Antwort Eclipse
Es ist kein technisches problem, aber Sie werden am Ende mit einer situation, wo der öffentlich verfügbaren Funktionen hängt davon ab, ob Sie eine Basis-oder abgeleitete Zeiger.
Dieser meiner Meinung nach wäre seltsam und verwirrend.
InformationsquelleAutor der Antwort Andrew Grant
Kann es sehr nützlich sein, wenn Sie mit privater Vererbung - d.h. Sie wiederverwenden möchten eine (individuelle) Funktionen von einer Basisklasse, aber nicht die Schnittstelle.
InformationsquelleAutor der Antwort Nemanja Trifunovic
Es kann getan werden, und ganz gelegentlich führen wird, zu nutzen. Zum Beispiel, in unserer codebase, wir verwenden eine Bibliothek enthält eine Klasse mit einer öffentlichen Funktion, die wir verwendet, um zu verwenden, aber jetzt raten von der Verwendung durch andere potenzielle Probleme (es gibt sicherere Methoden zu nennen). Auch wir haben zufällig eine Klasse von dieser Klasse abgeleitet, die eine Menge von unseren code verwendet, der direkt. So machten wir die gegebene Funktion private in der abgeleiteten Klasse um zu helfen, alle erinnern, es nicht zu verwenden, wenn Sie kann es helfen. Es beseitigt nicht die Möglichkeit, es zu benutzen, aber es wird fangen einige verwendet, wenn der code versucht zu kompilieren, anstatt später in die code-reviews.
InformationsquelleAutor der Antwort Caleb Huitt - cjhuitt
InformationsquelleAutor der Antwort MSN
Ein guter use-case für die private Vererbung ist ein Listener/Observer-Schnittstelle event.
Beispiel-code für die private object:
Einige Benutzer des Objekts, wollen die übergeordnete Funktionalität und einige wollen das Kind-Funktionalität:
Diese Weise die
AnimationList
halten kann ein Verweis auf die Eltern und Verwendungen, von übergeordneten Funktionen. Während dieSeal
hält eine Referenz auf das Kind und nutzt die einzigartigen Kind-Funktionalität und ignorieren die Eltern. In diesem Beispiel, dieSeal
sollte nicht nennenAnimate
. Nun, wie oben erwähnt,Animate
genannt werden kann, durch die Umwandlung der Basis-Objekt, aber das ist schwieriger und in der Regel nicht getan werden sollte.InformationsquelleAutor der Antwort hubatish