Schlitzauge schrieb:
3.) friend:
Kann mich mal einer zum friend-Spezifizierer aufklären?
Ich meine, ich sehe dahinter keinen Sinn, hebt dieser doch das Prinzip der Kapselung wieder auf?! Wozu gibt es diesen und kann mir mal jemand ein einfaches Beispiel zeigen, wo es Sinn macht, diesen einzusetzen? Die Beschreibungen und Beispiele im Netz und Büchern sind für mich mehr schlecht als recht.
friend ist eine Sache die man nicht oft braucht, aber wenn man es braucht, dann kann man damit die Kapselung verbessern, nicht aufbrechen.
friend schreibst du in die Klasse die Zugriff gewährt, jede Klasse kann also selbst entscheiden wer "darf" und wer "nicht darf".
Sogesehen wird also nichts aufgeweicht, denn wenn ich eine Klasse modifizieren kann, dann kann ich genau so gut gleich alle private: in public: umschreiben -- friend bringt hier also keine Verschlechterung.
Nur nebenbei: andere Sprachen bieten ähnliche Konstrukte an um das selbe zu erreichen, z.B. internal (C#) oder "package access" (Java). Der Unterschied dabei ist dass man mit internal bzw. "package access" genauer kontrollieren kann auf was zugegriffen werden darf, dafür weniger genau wer zugreifen darf.
OK, zurück zu "was soll das ganze?".
Beispiel: intrusive Datenstrukturen. Eine intrusive Map muss entweder Zugriff auf die im zu mappenden Element gespeicherte MapNode haben, oder die MapNode muss Zugriff auf die Map haben. Mit friend ganz einfach: die MapNode sagt friend Map und die Sache ist gegessen. Ohne friend muss man rumbasteln.
Etwas allgemeiner: wenn du zwei Klassen hast die eng zusammenarbeiten, für den User aber eben getrennte Klassen sein sollen, dann kann friend was bringen. Z.B. indem es dir ermöglicht ohne unnötigen Weiterleitungsfunktionen oder sonstige üble Tricks den Code einfach dort hinzuschreiben wo er hingehört.
Ein Beispiel dazu: Ein Renderer rendert, also gehört der Render-Code auch in den Renderer. Jetzt möchte der Renderer aber gerne auf Innereien einiger Renderables zugreifen -- z.B. weil er da drinnen irgendwelche Dinge cachen möchte. Vielleicht Texturen oder Shader oder Verwaltungsdaten für vom Renderer verwaltete Vertex-Buffer.
Also sagen die von der Library vordefinierten Renderables einfach friend Renderer , und er kann.
Ohne friend muss man auch hier entweder rumfrickeln, oder irgendwelche Implementierungsdetails allgemein zugänglich machen.
----
Nochwas: falls du das PIMPL Idiom kennst, dann denk man drüber nach was PIMPL und friend gemeinsam haben. Nämlich ziemlich viel wenn du mich fragst
(Und falls du es nicht kennt, dann schlag es nach.)
friend ermöglicht im Prinzip "PIMPL ohne Zeiger" . Dafür mit Inlining. Man könnte fast sagen: friend ist das bessere PIMPL.