Bearbeiten: Lesen der FAQ ein bisschen länger Ich mag die Idee der << >> Operator Überlastung und Hinzufügen als ein Freund dieser Klassen, aber ich bin nicht sicher, wie dies nicht brechen Kapselung
Inwiefern würde es die Verkapselung aufheben?
Sie brechen die Kapselung, wenn Sie erlauben Unbeschränkt Zugriff auf ein Datenelement. Betrachten Sie die folgenden Klassen:
class c1 {
public:
int x;
};
class c2 {
public:
int foo();
private:
int x;
};
class c3 {
friend int foo();
private:
int x;
};
c1
es natürlich nicht gekapselt. Jeder kann lesen und ändern x
darin. Wir haben keine Möglichkeit, irgendeine Art von Zugangskontrolle durchzusetzen.
c2
ist offensichtlich gekapselt. Es gibt keinen öffentlichen Zugang zu x
. Alles, was Sie tun können, ist den foo
Funktion, die Folgendes ausführt eine sinnvolle Operation an der Klasse .
c3
? Ist das weniger gekapselt? Erlaubt es uneingeschränkten Zugang zu x
? Erlaubt sie unbekannten Funktionen den Zugriff?
Nein. Es erlaubt genau eine Funktion, um auf die privaten Mitglieder der Klasse zuzugreifen. Genau wie c2
hat. Und genau wie c2
ist die einzige Funktion, die Zugriff hat, nicht "irgendeine beliebige, unbekannte Funktion", sondern "die in der Klassendefinition aufgeführte Funktion". Genau wie c2
können wir anhand der Klassendefinitionen erkennen, dass eine vollständig Liste der Personen, die Zugang haben.
Wie genau ist das weniger gekapselt? Die gleiche Menge an Code hat Zugriff auf die privaten Mitglieder der Klasse. Und alle wer Zugang hat, ist in der Klassendefinition aufgeführt.
friend
bricht nicht die Verkapselung. Einige Java-Programmierer fühlen sich dabei unwohl, denn wenn sie "OOP" sagen, meinen sie eigentlich mittlere "Java". Wenn sie "Kapselung" sagen, meinen sie nicht "private Mitglieder müssen vor willkürlichen Zugriffen geschützt werden", sondern "eine Java-Klasse, in der die einzigen Funktionen, die auf private Mitglieder zugreifen können, Klassenmitglieder sind", obwohl das völliger Unsinn ist aus mehreren Gründen .
Erstens ist sie, wie bereits dargelegt, zu restriktiv. Es gibt keinen Grund, warum die Methoden von Freunden nicht dasselbe tun sollten.
Zweitens ist sie nicht restriktiv genug . Betrachten Sie eine vierte Klasse:
class c4 {
public:
int getx();
void setx(int x);
private:
int x;
};
Dies ist, gemäß der oben erwähnten Java-Mentalität, perfekt gekapselt. Und doch erlaubt es absolut jedem, x . Wie kann das überhaupt einen Sinn ergeben? (Hinweis: Tut es nicht)
Unterm Strich: Bei der Kapselung geht es darum, dass man kontrollieren kann, welche Funktionen auf private Mitglieder zugreifen können. Sie ist nicht darüber, wo genau die Definitionen dieser Funktionen zu finden sind.