Ich habe die C ++ - FAQ gelesen und war neugierig auf die friend
Erklärung. Ich persönlich habe es nie benutzt, aber ich bin daran interessiert, die Sprache zu erkunden.
Was ist ein gutes Beispiel für die Verwendung friend
?
Wenn ich die FAQ etwas länger lese, mag ich die Idee, dass der <<
>>
Operator als Freund dieser Klassen überlastet und hinzufügt. Ich bin mir jedoch nicht sicher, wie dies die Kapselung nicht unterbricht. Wann können diese Ausnahmen innerhalb der Strenge bleiben, die OOP ist?
c++
oop
encapsulation
friend
Peter Mortensen
quelle
quelle
Antworten:
Erstens (IMO) hören Sie nicht auf Leute, die sagen, dass dies
friend
nicht nützlich ist. Es ist nützlich. In vielen Situationen verfügen Sie über Objekte mit Daten oder Funktionen, die nicht öffentlich verfügbar sein sollen. Dies gilt insbesondere für große Codebasen mit vielen Autoren, die möglicherweise nur oberflächlich mit verschiedenen Bereichen vertraut sind.Es gibt Alternativen zum Friend-Bezeichner, aber oft sind sie umständlich (konkrete Klassen auf CPP-Ebene / maskierte Typedefs) oder nicht narrensicher (Kommentare oder Konventionen für Funktionsnamen).
Auf die Antwort;
Der
friend
Bezeichner ermöglicht der angegebenen Klasse den Zugriff auf geschützte Daten oder Funktionen innerhalb der Klasse, die die friend-Anweisung abgeben. Zum Beispiel kann im folgenden Code jeder ein Kind nach seinem Namen fragen, aber nur die Mutter und das Kind dürfen den Namen ändern.Sie können dieses einfache Beispiel weiterführen, indem Sie eine komplexere Klasse wie ein Fenster betrachten. Sehr wahrscheinlich wird ein Fenster viele Funktions- / Datenelemente haben, die nicht öffentlich zugänglich sein sollten, aber von einer verwandten Klasse wie einem WindowManager benötigt werden.
quelle
friend
die Kapselung verbessert wird .friend
gewährt Mitgliedern selektiven Zugang , genau wie dies derprotected
Fall ist. Eine fein abgestimmte Kontrolle ist besser als die Gewährung eines öffentlichen Zugangs. Andere Sprachen definieren auch selektive Zugriffsmechanismen, berücksichtigen Sie C #internal
. Die meiste negative Kritik an der Verwendung vonfriend
bezieht sich auf eine engere Kopplung, was allgemein als eine schlechte Sache angesehen wird. In einigen Fällen ist eine engere Kopplung jedoch genau das, was Sie wollen, undfriend
gibt Ihnen diese Kraft.friend
ist, als ein motivierendes Beispiel zu liefern . Das Window / WindowManager-Beispiel ist besser als das gezeigte Beispiel, aber zu vage. Diese Antwort behandelt auch nicht den Kapselungsteil der Frage.Bei der Arbeit verwenden wir Freunde, um Code ausgiebig zu testen . Dies bedeutet, dass wir eine ordnungsgemäße Kapselung und Verstecken von Informationen für den Hauptanwendungscode bereitstellen können. Wir können aber auch einen separaten Testcode verwenden, der Freunde verwendet, um den internen Status und die Daten zum Testen zu überprüfen.
Es genügt zu sagen, dass ich das Schlüsselwort friend nicht als wesentlichen Bestandteil Ihres Designs verwenden würde.
quelle
Das
friend
Schlüsselwort hat eine Reihe von Verwendungsmöglichkeiten. Hier sind die beiden für mich sofort sichtbaren Verwendungen:Freund Definition
Mit der Friend-Definition kann eine Funktion im Klassenbereich definiert werden. Die Funktion wird jedoch nicht als Elementfunktion, sondern als freie Funktion des umschließenden Namespace definiert und ist normalerweise nur für die argumentabhängige Suche sichtbar. Das macht es besonders nützlich für die Überlastung des Bedieners:
Private CRTP-Basisklasse
Manchmal müssen Sie feststellen, dass eine Richtlinie Zugriff auf die abgeleitete Klasse benötigt:
In dieser Antwort finden Sie ein nicht erfundenes Beispiel dafür . Ein anderer Code, der dies verwendet, ist in dieser Antwort enthalten. Die CRTP-Basis wandelt diesen Zeiger um, um mithilfe von Datenelementzeigern auf Datenfelder der abgeleiteten Klasse zugreifen zu können.
quelle
P<C>
in dietemplate<template<typename> class P> class C : P<C> {};
besagt , „Verwendung von Klassenvorlage C Vorlage Argumente erfordert“. Haben Sie die gleichen Probleme oder kennen Sie vielleicht eine Lösung?FlexibleClass
innerhalbFlexibleClass
sollte sich implizit auf seinen eigenen Typ beziehen.@roo : Die Kapselung wird hier nicht unterbrochen, da die Klasse selbst vorschreibt, wer auf ihre privaten Mitglieder zugreifen darf. Die Kapselung würde nur dann unterbrochen, wenn dies von außerhalb der Klasse verursacht werden könnte, z. B. wenn Sie
operator <<
verkünden würden, dass ich ein Freund der Klasse binfoo
.friend
ersetzt die Verwendung vonpublic
, nicht die Verwendung vonprivate
!Tatsächlich beantworten die C ++ - FAQ dies bereits .
quelle
friend
ist keine Ausnahme. Die einzige wirkliche Beobachtung hier ist, dass C ++ die Kapselung nur zur Kompilierungszeit sicherstellt. Und Sie brauchen keine Worte mehr, um es zu sagen. Der Rest ist Blödsinn. Zusammenfassend: Dieser Abschnitt der FQA ist nicht erwähnenswert.Das kanonische Beispiel ist das Überladen des Operators <<. Eine weitere häufige Verwendung besteht darin, einem Helfer oder einer Administratorklasse den Zugriff auf Ihre Interna zu ermöglichen.
Hier sind einige Richtlinien, die ich über C ++ - Freunde gehört habe. Der letzte ist besonders denkwürdig.
quelle
friend
denke ich.Wie würde es die Kapselung brechen?
Sie unterbrechen die Kapselung, wenn Sie uneingeschränkten Zugriff auf ein Datenelement zulassen . Betrachten Sie die folgenden Klassen:
c1
ist offensichtlich nicht eingekapselt. Jeder kann es lesen und ändernx
. Wir haben keine Möglichkeit, irgendeine Art von Zugangskontrolle durchzusetzen.c2
ist offensichtlich eingekapselt. Es gibt keinen öffentlichen Zugang zux
. Sie können lediglich diefoo
Funktion aufrufen , die eine sinnvolle Operation für die Klasse ausführt .c3
? Ist das weniger gekapselt? Ermöglicht es uneingeschränkten Zugriff aufx
? Ermöglicht es den Zugriff auf unbekannte Funktionen?Nein. Es ermöglicht genau einer Funktion, auf die privaten Mitglieder der Klasse zuzugreifen. Genau wie
c2
. Und genau wiec2
die einzige Funktion, die Zugriff hat, ist nicht "eine zufällige, unbekannte Funktion", sondern "die in der Klassendefinition aufgeführte Funktion". Genausoc2
können wir anhand der Klassendefinitionen eine vollständige Liste der Personen sehen, die Zugriff haben.Wie genau ist das weniger gekapselt? Die gleiche Menge an Code hat Zugriff auf die privaten Mitglieder der Klasse. Und jeder , der Zugriff hat, ist in der Klassendefinition aufgeführt.
friend
bricht die Kapselung nicht. Einige Java-Programmierer fühlen sich unwohl, denn wenn sie "OOP" sagen, meinen sie tatsächlich "Java". Wenn sie „Encapsulation“ sagen, meinen sie nicht, sondern „eine Java - Klasse , wo die einzigen Funktionen der Lage , den Zugang private Mitglieder, sind die Teilnehmer“ „private Mitglieder müssen vor willkürlichen Zugriffen geschützt werden“, auch wenn dies völliger Unsinn ist für mehrere Gründe .Erstens ist es, wie bereits gezeigt, zu einschränkend. Es gibt keinen Grund, warum Freundmethoden nicht dasselbe tun dürfen.
Zweitens ist es nicht restriktiv genug . Betrachten Sie eine vierte Klasse:
Dies ist gemäß der oben genannten Java-Mentalität perfekt gekapselt. Und doch erlaubt es absolut jedem, x zu lesen und zu modifizieren . Wie macht das überhaupt Sinn? (Hinweis: Nicht)
Fazit: Bei der Kapselung geht es darum, steuern zu können, welche Funktionen auf private Mitglieder zugreifen können. Es geht nicht genau darum, wo sich die Definitionen dieser Funktionen befinden.
quelle
Eine weitere gängige Version von Andrews Beispiel ist das gefürchtete Code-Couplet
Anstatt sich Sorgen zu machen, ob beide Zeilen immer zusammen und in konsistenter Reihenfolge ausgeführt werden, können Sie die Methoden privat machen und eine Friend-Funktion haben, um die Konsistenz zu erzwingen:
Mit anderen Worten, Sie können die öffentlichen Schnittstellen kleiner halten und Invarianten erzwingen, die Klassen und Objekte in Friend-Funktionen überschneiden.
quelle
addChild
Mitgliedsfunktion auch das übergeordnete Element festlegen lassen?setParent
einen Freund, wie Sie Clients wollen , damit die Eltern sich ändern , da Sie es in der Verwaltung werdeaddChild
/removeChild
Kategorie von Funktionen.Sie steuern die Zugriffsrechte für Mitglieder und Funktionen mit privaten / geschützten / öffentlichen Rechten? Wenn also die Idee jeder dieser drei Ebenen klar ist, sollte klar sein, dass uns etwas fehlt ...
Die Deklaration eines Mitglieds / einer Funktion als geschützt ist beispielsweise ziemlich allgemein. Sie sagen, dass diese Funktion für alle unerreichbar ist (außer natürlich für ein geerbtes Kind). Aber was ist mit Ausnahmen? Mit jedem Sicherheitssystem können Sie eine Art "weiße Liste" haben, oder?
Mit Friend haben Sie die Flexibilität, eine solide Objektisolierung zu haben, aber es kann eine "Lücke" für Dinge geschaffen werden, die Sie für gerechtfertigt halten.
Ich denke, die Leute sagen, dass es nicht benötigt wird, weil es immer ein Design gibt, das ohne es auskommt. Ich denke, es ist ähnlich wie bei der Diskussion globaler Variablen: Sie sollten sie niemals verwenden. Es gibt immer einen Weg, auf sie zu verzichten. In Wirklichkeit sehen Sie jedoch Fälle, in denen dies der (fast) eleganteste Weg ist. Ich denke, das ist der gleiche Fall mit Freunden.
Nun, das ist nicht genau die Art, es zu betrachten. Die Idee ist zu kontrollieren, wer auf etwas zugreifen kann, ob eine Einstellungsfunktion wenig damit zu tun hat oder nicht .
quelle
friend
eine Lücke? Damit können die in der Klasse aufgeführten Methoden auf ihre privaten Mitglieder zugreifen. Es kann immer noch kein beliebiger Code darauf zugreifen. Als solches unterscheidet es sich nicht von einer öffentlichen Mitgliederfunktion.Ich fand einen praktischen Ort, um den Zugang von Freunden zu nutzen: Unittest von privaten Funktionen.
quelle
Friend ist praktisch, wenn Sie einen Container erstellen und einen Iterator für diese Klasse implementieren möchten.
quelle
Wir hatten ein interessantes Problem bei einer Firma, bei der ich zuvor gearbeitet habe, bei der wir Freunde für anständige Affekte eingesetzt haben. Ich habe in unserer Framework-Abteilung gearbeitet. Wir haben ein grundlegendes System auf Engine-Ebene über unser benutzerdefiniertes Betriebssystem erstellt. Intern hatten wir eine Klassenstruktur:
Alle diese Klassen waren Teil des Rahmens und wurden von unserem Team gepflegt. Die von der Firma produzierten Spiele wurden auf diesem Framework aufgebaut, das von einem der Games-Kinder stammt. Das Problem war, dass Game Schnittstellen zu verschiedenen Dingen hatte, auf die SinglePlayer und TwoPlayer Zugriff benötigen, die wir jedoch nicht außerhalb der Framework-Klassen verfügbar machen wollten. Die Lösung bestand darin, diese Schnittstellen privat zu machen und TwoPlayer und SinglePlayer über eine Freundschaft auf sie zuzugreifen.
Ehrlich gesagt hätte dieses ganze Problem durch eine bessere Implementierung unseres Systems gelöst werden können, aber wir waren an das gebunden, was wir hatten.
quelle
Die kurze Antwort wäre: Freund benutzen, wenn es sich tatsächlich verbessert Kapselung . Die Verbesserung der Lesbarkeit und Benutzerfreundlichkeit (Operatoren << und >> sind das kanonische Beispiel) ist ebenfalls ein guter Grund.
Beispiele für die Verbesserung der Kapselung sind Klassen, die speziell für die Zusammenarbeit mit den Interna anderer Klassen entwickelt wurden (Testklassen fallen mir ein).
quelle
<<
und>>
sind normalerweise Freunde anstelle von Mitgliedern, da die Verwendung zu Mitgliedern die Verwendung umständlich macht. Ich spreche natürlich von dem Fall, in dem diese Betreiber auf private Daten zugreifen müssen. Ansonsten ist Freundschaft nutzlos.operator<<
undoperator>>
Mitglieder der Wertklasse statt Nicht-Mitglieder oder Mitgliederi|ostream
, würden die gewünschte Syntax nicht zur Verfügung stellen, und ich bin nicht darauf hindeutet es. " Ich spreche von dem Fall, in dem diese Betreiber auf private Daten zugreifen müssen. " Ich verstehe nicht ganz, warum die Eingabe- / Ausgabeoperatoren auf private Mitglieder zugreifen müssen.Der Schöpfer von C ++ sagt, dass dies kein Kapselungsprinzip vermittelt, und ich werde ihn zitieren:
Ist mehr als klar ...
quelle
Eine andere Verwendung: Freund (+ virtuelle Vererbung) kann verwendet werden, um das Ableiten von einer Klasse zu vermeiden (auch bekannt als "eine Klasse unteraktivierbar machen") => 1 , 2
Ab 2 :
quelle
Um TDD oft zu machen, habe ich in C ++ das Schlüsselwort 'friend' verwendet.
Kann ein Freund alles über mich wissen?
Aktualisiert: Ich habe diese wertvolle Antwort zum Schlüsselwort "Freund" von der Bjarne Stroustrup-Website gefunden .
quelle
Sie müssen sehr vorsichtig sein, wann / wo Sie das
friend
Schlüsselwort verwenden, und wie Sie habe ich es sehr selten verwendet. Nachfolgend finden Sie einige Hinweise zur Verwendungfriend
und zu den Alternativen.Angenommen, Sie möchten zwei Objekte vergleichen, um festzustellen, ob sie gleich sind. Sie könnten entweder:
Das Problem mit der ersten Option ist, dass dies eine Menge Accessoren sein können, die (etwas) langsamer als der direkte variable Zugriff, schwerer zu lesen und umständlich sind. Das Problem beim zweiten Ansatz besteht darin, dass Sie die Kapselung vollständig unterbrechen.
Was schön wäre, wäre, wenn wir eine externe Funktion definieren könnten, die immer noch Zugriff auf die privaten Mitglieder einer Klasse erhalten könnte. Wir können dies mit dem
friend
Schlüsselwort tun :Das Verfahren
equal(Beer, Beer)
hat nun direkten Zugriff aufa
undb
‚s private Mitglieder (was sein kannchar *brand
,float percentAlcohol
usw. Dies ist ein ziemlich konstruiertes Beispiel, Sie früher anwenden würde ,friend
um eine überladene== operator
, aber wir werden auf das bekommen.Ein paar Dinge zu beachten:
friend
ist KEINE Mitgliedsfunktion der Klassepublic
!)Ich benutze
friends
es nur dann wirklich, wenn es viel schwieriger ist, es andersherum zu machen. Als weiteres Beispiel sind viele Vektor - Mathematik - Funktionen oft erstelltfriends
aufgrund der InteroperabilitätMat2x2
,Mat3x3
,Mat4x4
,Vec2
,Vec3
,Vec4
, etc. Und es ist nur so viel einfacher , Freunde zu sein, anstatt zu haben Accessoren überall zu nutzen. Wie bereits erwähnt,friend
ist es oft nützlich, wenn es auf das<<
(sehr praktisch zum Debuggen)>>
und möglicherweise auf den==
Operator angewendet wird, kann aber auch für Folgendes verwendet werden:Wie gesagt, ich benutze es nicht
friend
sehr oft, aber hin und wieder ist es genau das, was du brauchst. Hoffe das hilft!quelle
In Bezug auf Operator << und Operator >> gibt es keinen guten Grund, diese Operatoren zu Freunden zu machen. Es ist wahr, dass sie keine Mitgliedsfunktionen sein sollten, aber sie müssen auch keine Freunde sein.
Am besten erstellen Sie öffentliche Druck- (ostream &) und Lesefunktionen (istream &). Schreiben Sie dann den Operator << und den Operator >> in Bezug auf diese Funktionen. Dies bietet den zusätzlichen Vorteil, dass Sie diese Funktionen virtuell gestalten können, was eine virtuelle Serialisierung ermöglicht.
quelle
Ich verwende das Freund-Schlüsselwort nur, um geschützte Funktionen zu testen. Einige werden sagen, dass Sie geschützte Funktionen nicht testen sollten. Ich finde dieses Tool jedoch sehr nützlich, wenn ich neue Funktionen hinzufüge.
Ich verwende das Schlüsselwort jedoch nicht direkt in den Klassendeklarationen, sondern verwende einen raffinierten Template-Hack, um dies zu erreichen:
Dies ermöglicht mir Folgendes:
Funktioniert mindestens mit GCC und MSVC.
quelle
In C ++ ist das Schlüsselwort "friend" beim Überladen von Operatoren und beim Erstellen von Bridge hilfreich.
Jetzt ist die erste Option nicht gut, denn wenn wir diesen Operator für eine andere Klasse erneut überladen müssen, müssen wir erneut Änderungen in der "ostream" -Klasse vornehmen.1.) Friend-Schlüsselwort beim Überladen von Operatoren:
Beispiel für das Überladen von Operatoren ist: Angenommen, wir haben eine Klasse "Point" mit zwei Gleitkommavariablen
"x" (für x-Koordinate) und "y" (für y-Koordinate). Jetzt müssen wir überladen
"<<"
(Extraktionsoperator), so dass, wenn wir aufrufen"cout << pointobj"
die x- und y-Koordinate gedruckt wird (wobei pointobj ein Objekt der Klasse Point ist). Dazu haben wir zwei Möglichkeiten:Deshalb ist die zweite Option die beste. Jetzt kann der Compiler die
"operator <<()"
Funktion aufrufen :Weil wir eine Überladung in der Point-Klasse implementiert haben. Um diese Funktion ohne Objekt aufzurufen, müssen wir ein
"friend"
Schlüsselwort hinzufügen, da wir eine Friend-Funktion ohne Objekt aufrufen können. Jetzt lautet die Funktionsdeklaration wie folgt:"friend ostream &operator<<(ostream &cout, Point &pointobj);"
2.) Schlüsselwort Friend bei der Erstellung einer Brücke:
Angenommen, wir müssen eine Funktion erstellen, in der wir auf ein privates Mitglied von zwei oder mehr Klassen zugreifen müssen (im Allgemeinen als "Brücke" bezeichnet). Vorgehensweise:
Um auf ein privates Mitglied einer Klasse zugreifen zu können, sollte es Mitglied dieser Klasse sein. Um nun auf ein privates Mitglied einer anderen Klasse zugreifen zu können, sollte jede Klasse diese Funktion als Freundfunktion deklarieren. Beispiel: Angenommen, es gibt zwei Klassen A und B. Eine Funktion
"funcBridge()"
möchte auf ein privates Mitglied beider Klassen zugreifen. Dann sollten beide Klassen deklarieren"funcBridge()"
als:friend return_type funcBridge(A &a_obj, B & b_obj);
Ich denke, dies würde helfen, das Schlüsselwort "Freund" zu verstehen.
quelle
Wie die Referenz für die Erklärung eines Freundes sagt:
Nur zur Erinnerung, es gibt technische Fehler in einigen der Antworten, die besagen, dass
friend
nur geschützte Mitglieder besucht werden können.quelle
Das Baumbeispiel ist ein ziemlich gutes Beispiel: Ein Objekt in einer anderen Klasse implementieren zu lassen, ohne eine Vererbungsbeziehung zu haben.
Vielleicht brauchen Sie es auch, um einen Konstruktor zu schützen und die Leute zu zwingen, Ihre "Freund" -Fabrik zu benutzen.
... Ok, ehrlich gesagt kannst du ohne leben.
quelle
Nein, es ist nur eine Einbahnstraße: `(
quelle
Eine spezielle Instanz, die ich verwende,
friend
ist das Erstellen von Singleton- Klassen. Mit demfriend
Schlüsselwort kann ich eine Accessor-Funktion erstellen, die präziser ist als immer eine "GetInstance ()" - Methode für die Klasse.quelle
friend
ist nicht eine bestimmte „Rechtfertigung“ muß, wenn eine Member - Funktion Hinzufügen nicht.Friend-Funktionen und -Klassen bieten direkten Zugriff auf private und geschützte Mitglieder der Klasse, um zu vermeiden, dass die Kapselung im allgemeinen Fall unterbrochen wird. Die meiste Verwendung erfolgt mit ostream: Wir möchten Folgendes eingeben können:
Dies kann jedoch den Zugriff auf die privaten Daten von Point erfordern, daher definieren wir den überladenen Operator
Es gibt jedoch offensichtliche Auswirkungen auf die Verkapselung. Erstens hat die Freundesklasse oder -funktion jetzt vollen Zugriff auf ALLE Mitglieder der Klasse, auch auf diejenigen, die nicht ihren Anforderungen entsprechen. Zweitens sind die Implementierungen der Klasse und des Freundes jetzt so eng miteinander verbunden, dass eine interne Änderung in der Klasse den Freund beschädigen kann.
Wenn Sie den Freund als Erweiterung der Klasse betrachten, ist dies logischerweise kein Problem. Aber warum war es in diesem Fall überhaupt notwendig, den Freund auszuspießen?
Um dasselbe zu erreichen, was "Freunde" vorgeben zu erreichen, ohne jedoch die Kapselung zu unterbrechen, kann man dies tun:
Die Kapselung ist nicht unterbrochen, Klasse B hat keinen Zugriff auf die interne Implementierung in A, aber das Ergebnis ist das gleiche, als hätten wir B als Freund von A deklariert. Der Compiler optimiert die Funktionsaufrufe, sodass dies dasselbe ergibt Anweisungen als direkter Zugriff.
Ich denke, die Verwendung von "Freund" ist einfach eine Abkürzung mit fraglichem Nutzen, aber bestimmten Kosten.
quelle
Dies ist möglicherweise keine tatsächliche Anwendungsfallsituation, kann jedoch dazu beitragen, die Verwendung von Freunden zwischen Klassen zu veranschaulichen.
Das Clubhaus
Die Mitgliederklasse
Ausstattung
Wenn Sie sich hier die Beziehung dieser Klassen ansehen; Das ClubHouse bietet verschiedene Arten von Mitgliedschaften und Zugang zu Mitgliedern. Die Mitglieder werden alle von einer Super- oder Basisklasse abgeleitet, da sie alle eine gemeinsame ID und einen Aufzählungstyp gemeinsam haben und externe Klassen über Zugriffsfunktionen in der Basisklasse auf ihre IDs und Typen zugreifen können.
Aufgrund dieser Art von Hierarchie der Mitglieder und ihrer abgeleiteten Klassen und ihrer Beziehung zur ClubHouse-Klasse ist die VIPMember-Klasse die einzige der abgeleiteten Klassen, die "besondere Berechtigungen" besitzt. Die Basisklasse und die anderen beiden abgeleiteten Klassen können nicht auf die joinVIPEvent () -Methode des ClubHouse zugreifen. Die VIP-Mitgliedsklasse verfügt jedoch über dieses Privileg, als hätte sie vollständigen Zugriff auf dieses Ereignis.
Mit dem VIPMember und dem ClubHouse ist es also eine Einbahnstraße in beide Richtungen, in der die anderen Mitgliederklassen begrenzt sind.
quelle
Bei der Implementierung von Baumalgorithmen für Klassen hatte der Framework-Code, den der Professor uns gegeben hatte, die Baumklasse als Freund der Knotenklasse.
Es nützt nichts, außer dass Sie auf eine Mitgliedsvariable zugreifen können, ohne eine Einstellungsfunktion zu verwenden.
quelle
Sie können Freundschaft verwenden, wenn verschiedene Klassen (die nicht voneinander erben) private oder geschützte Mitglieder der anderen Klasse verwenden.
von http://www.cplusplus.com/doc/tutorial/inheritance/ .
Sie können dieses Beispiel sehen, in dem eine Nichtmitgliedsmethode auf die privaten Mitglieder einer Klasse zugreift. Diese Methode muss in dieser Klasse als Freund der Klasse deklariert werden.
quelle
Wahrscheinlich habe ich etwas von den obigen Antworten verpasst, aber ein weiteres wichtiges Konzept bei der Kapselung ist das Verstecken der Implementierung. Das Reduzieren des Zugriffs auf private Datenelemente (die Implementierungsdetails einer Klasse) ermöglicht später eine wesentlich einfachere Änderung des Codes. Wenn ein Freund direkt auf die privaten Daten zugreift und alle Änderungen an den Implementierungsdatenfeldern (privaten Daten) vorgenommen werden, wird der Code, der auf diese Daten zugreift, unterbrochen. Die Verwendung von Zugriffsmethoden beseitigt dies größtenteils. Ziemlich wichtig würde ich denken.
quelle
Sie können die strengsten und reinsten OOP-Prinzipien einhalten und sicherstellen, dass keine Datenelemente für eine Klasse über Zugriffsmethoden verfügen, sodass alle Objekte die einzigen sein müssen , die über ihre Daten Bescheid wissen können. Die einzige Möglichkeit, auf sie zu reagieren, sind indirekte Nachrichten , sind . dh Methoden.
Aber auch C # hat ein internes Sichtbarkeitsschlüsselwort und Java hat für einige Dinge die Standardzugriffsfähigkeit auf Paketebene . C ++ kommt dem OOP-Ideal tatsächlich näher, indem der Kompromiss der Sichtbarkeit in eine Klasse minimiert wird, indem genau angegeben wird , welche andere Klasse und nur andere Klassen in sie hinein sehen können.
Ich benutze C ++ nicht wirklich, aber wenn C # Freunde hätte, würde ich das anstelle des Assembly-globalen internen Modifikators tun , den ich tatsächlich oft benutze. Die Kapselung wird nicht wirklich unterbrochen, da die Bereitstellungseinheit in .NET ist eine Montage.
Aber dann gibt es das InternalsVisibleTo- Attribut (otherAssembly), das sich wie ein montageübergreifender Freundschaftsmechanismus verhält . Microsoft verwendet dies für visuelle Designer- Assemblys.
quelle
Freunde sind auch nützlich für Rückrufe. Sie können Rückrufe als statische Methoden implementieren
wo
callback
AnrufelocalCallback
intern und dieclientData
hat Ihre Instanz drin. Meiner Meinung nach,oder...
Dies ermöglicht es dem Freund, rein im cpp als c-artige Funktion definiert zu werden und die Klasse nicht zu überladen.
Ebenso ist ein Muster, das ich sehr oft gesehen habe, alles wirklich zu sagen privaten Mitglieder einer Klasse in eine andere Klasse zu setzen, die im Header deklariert, im cpp definiert und befreundet ist. Dies ermöglicht es dem Codierer, einen Großteil der Komplexität und internen Arbeitsweise der Klasse vor dem Benutzer des Headers zu verbergen.
In der Kopfzeile:
In der cpp,
Es wird einfacher, Dinge zu verbergen, die der Downstream nicht so sehen muss.
quelle