Ich versuche, C ++ Freund zu verstehen. Wann ist der gute Anwendungsfall, um Freund zu verwenden? Ich nehme an, wenn wir einer anderen Klasse Zugriff auf andere Klassenattribute gewähren möchten, warum machen wir es dann nicht einfach als öffentlich oder erben stattdessen von dieser Klasse?
Danke für deine Hilfe.
Antworten:
Um ein Mitglied der Klasse zu werden
public
, muss jeder Zugriff darauf erhalten, wodurch die Kapselung vollständig unterbrochen wird.Das Erben einer Klasse ist oft nicht wünschenswert, wenn die Freundesklasse keine Unterklasse sein soll. Das Unterklassen nur, um Zugriff auf die Interna einer Klasse zu erhalten, ist ein schwerwiegender Designfehler. Und selbst eine Unterklasse kann die privaten Mitglieder ihrer Basisklasse nicht sehen.
Eine typische Verwendung von
friend
ist für Operatoren, die keine Mitglieder sein können, wie z. B. Stream-Operatorenoperator+
usw. In diesen Fällen ist die tatsächliche Klasse, der sie zugeordnet sind, nicht (immer) der erste Parameter der Funktion, daher kann die Funktion dies nicht als Mitgliedsmethode implementiert werden.Ein weiteres Beispiel ist die Implementierung eines Iterators für eine Sammlung. Der Iterator (und nur der Iterator) muss die Interna seiner übergeordneten Sammlung sehen, ist jedoch keine Unterklasse der Sammlung.
quelle
Das Beispiel, für das ich in C ++ am häufigsten Freundklassen gesehen habe, ist das Testen von Einheiten. Unit-Tests möchten normalerweise alles über Ihre Interna wissen, sind aber nicht Teil von Ihnen, und es macht keinen Sinn, wenn sie versuchen, von Ihnen zu erben.
Wenn Sie mit dem Schreiben von Unit - Tests nicht vertraut sind, würde ich vorschlagen , dass Sie beginnen sofort.
quelle
Diese Frage sollte sich auf Stackoverflow beziehen. Auf jeden Fall verwenden Sie einen Freund nur, wenn Sie die privaten Teile Ihrer Klasse mit einer anderen Klasse (oder Klassen) teilen möchten, aber nicht mit anderen. Wenn Sie sie öffentlich machen, kann jeder Ihre privaten Teile sehen (Wortspiel beabsichtigt ;-P). Es gibt zwei wichtige Einschränkungen, die den Datenschutz erzwingen: 1) Sie müssen angeben, wer Ihr Freund ist. Niemand sonst kann ein Freund sein. 2) Sie können kein "freundliches" Verhalten in den Unterklassen der Freundesklasse erben
quelle
Eine typische Verwendung besteht darin, Zugriff auf Funktionen zu gewähren, die Teil der Klassenschnittstelle sind, aber dank anderer Regeln nicht wirklich Teil der eigentlichen Klasse sein können. Inserter / Extraktoren für iostreams sind ein klassisches Beispiel:
Es funktioniert nicht, diese Operatoren zu Mitgliedern der Klasse zu machen. Eine E / A-Operation sieht ungefähr so aus:
Für einen Operator, der als Mitgliedsfunktion implementiert ist, wird dies wie folgt gelöst:
Das heißt, die Funktion müsste Mitglied von sein
std::cout
, nicht vonsomething
. Da wir nichtstd::ostream
ständig Änderungen vornehmen möchten , besteht unsere einzig sinnvolle Option darin, den Operator mit einer freien Funktion anstelle einer Mitgliedsfunktion zu überladen. Das lässt uns zwei Möglichkeiten: entweder die Kapselung vollständig ignorieren und alles in der Klasse öffentlich machen oder es privat halten, aber Zugriff auf die wenigen Dinge gewähren, die es wirklich brauchen.Eine andere Klasse zu einem Freund zu machen, ist eher selten. In diesem Fall erstellen Sie normalerweise etwas in der Größenordnung eines Moduls oder Subsystems - eine Reihe von Klassen, die zusammenarbeiten und einen gewissen besonderen Zugriff aufeinander haben, der der Welt insgesamt nicht gewährt wird.
quelle
Es gibt ein ziemlich gutes Beispiel für die Notwendigkeit von Freundklassen in dieser Anfrage für freundähnliche Klassen in C # , einer Sprache, in der sie nicht vorhanden sind.
Hier im Großhandel zitiert:
Mads Torgersen, PM von C # Language, hat sogar auf diesen Vorschlag geantwortet und erklärt, dass das Anliegen zwar berechtigt ist, sich jedoch nicht sicher ist, welche spezifische Implementierung dort vorgeschlagen wird.
C ++
friend
ist nur eine der Möglichkeiten, um das beschriebene Problem zu lösen.quelle
Wenn Sie möchten, dass Ihre Klassen monogame Beziehungen haben.
Zum Beispiel, wenn Sie nicht möchten, dass unbekannte Klassen auf ihre Privaten zugreifen, ihre Partner jedoch Zugriff benötigen.
quelle
Ich habe festgestellt, dass Freundklassen in C ++ nützlich sind, wenn ich in Java den Paketzugriff verwendet hätte. Das heißt, ich habe eine Reihe von Klassen, die so eng miteinander verbunden sind, dass sie als Einheit in derselben Quelldatei (en) geschrieben und verwaltet werden. Jeder, der an einem von ihnen arbeitet, arbeitet wirklich an allen. Die Invarianten, die sie pflegen, pflegen sie zusammen. Es ist sinnvoll, dass sie die Interna des anderen sehen, damit sie ihre gemeinsame Invariante beibehalten können.
Was keinen Sinn ergibt, ist ein geschützter Zugang. Wenn es nicht sicher ist, einen Teil meiner Interna der Öffentlichkeit zugänglich zu machen, ist es nicht sicher, ihn den Jackanapes auszusetzen, die später in einem völlig unabhängigen Projekt auftauchen und behaupten, meine Unterklasse zu sein. Lassen Sie Unterklassen meine öffentliche Schnittstelle verwenden, genau wie alle anderen. (Es sei denn, sie sind Freunde, aber in diesem Fall habe ich sie geschrieben und in derselben Quelle implementiert, sodass sie kaum aus einem anderen Projekt stammen.)
quelle
Nehmen wir an, es gibt eine externe Funktion, bei der Sie Operationen an privaten oder geschützten Mitgliedern zweier verschiedener Klassen in Ihrem Programm ausführen müssen. Damit diese Funktion Zugriff auf diese Klassenmitglieder erhält und diese tatsächlich verwendet, müssen Sie sie zu einem Freund beider Klassen machen. Wenn man bedenkt, dass wenn man es zu einem Freund dieser beiden Klassen macht, es nicht zu einem Mitglied der Klassen wird, erhält man nur die Vorstufe, sich auf die privaten oder geschützten Mitglieder dieser Klassen zu beziehen. Ich kann sagen, dass Sie eine Friend-Funktion verwenden müssten, wenn Sie Objekte aus zwei verschiedenen Klassen bearbeiten möchten. Obwohl die Überbeanspruchung von Freundfunktion und Klasse den Wert der Kapselung verringern kann.
quelle