Datenkapselung und 'friend'
-
Hey,
mal eine eher grundsätzliche Frage:
C++ erlaubt es ja, mit dem friend-Keyword auf private elemente einer Klasse zuzugreifen.
Angenommen ich schreibe eine Library 'libFoo' für irgendwas und jemand bindet diese Library in sein Programm ein und inkludiert dazu den Header 'libFoo.h', wo die Klassendeklaration drin ist:class CFoo { public: //bla protected: //bla private: string mGeheimerText; };Natürlich will ich als Entwickler mir nicht in die Karten schauen lassen, deswegen ist mGeheimerText auch private.
Der Benutzer der Library könnte aber doch jederzeit den Header bearbeiten und seine Funktionen und Klassen als Freunde reinschreiben und somit auf meine privaten Daten zugreifen.Man könnte das natürlich so mit einer forward declaration umgehen:
class GeheimeDatenKlasse; class CFoo { public: //bla protected: //bla private: GeheimeDatenKlasse mGeheim; };Die Schnittstelle für GeheimeDatenKlasse hat der User natürlich nicht aber ich finde diese Lösung sehr unelegant.
Gibts da nicht was schlaueres oder steh ich im Moment auf dem Schlauch?Grüße
FellaR
-
jepp das könnte er:) aber was bringt ihm?
-
Der User verfügt ja nicht über die Deklaration (und Definition) von GeheimeDatenKlasse, also kann er auch nicht wissen, was darin zu finden ist, geschweige denn auf die Daten darin zugreifen.
Oder sehe ich was falsch?
-
Du kannst keine vorwärts deklarierten Objekte definieren, darum geht dein Code auch nicht. Mit ein paar Tricks geht es dennoch. Suche mal nach Pimpl- oder Handle-Body-Idiom.
Wenn jemand wirklich Zugriff auf die Innereien einer Klasse will so kommt er immer per Casts ran. Nur eben kriegt er Probleme falls du sie änderst.
Das Ziel von Zugriffsrechten ist es nicht das Hacken unmöglich zu machen sondern versehentliche Fehler zu finden. Solange man die Kettensäge zuhause lässt findet der Compiler alles was Probleme mit der Kapslung machen könnte.
Das Ziel der Kapselung ist es bei der Organisation eines Programms zu helfen, nicht vor Raub zu schützen.
-
deshalb sollte man auch lieber von sichtbarkeit und nicht "zugriffsrecht" sprechen.
-
thordk schrieb:
deshalb sollte man auch lieber von sichtbarkeit und nicht "zugriffsrecht" sprechen.
Sichtbarkeit ist auch nicht gut, weil private Daten sind sichtbar! Zu mindest können sie andere Daten verdecken. Zum Beispiel:
struct Foo{ int foo; }; class Bar:public Foo{ private: int foo; }; int main(){ Bar bar; bar.foo = 4; // Bum }
-
public und privat sind nicht zur Sicherheit gemacht, die wurden zur Strukturierung und Fehlervermeidung erfunden. Binär ist es dann egal, ob es irgendwann man public oder private war. Warum sollte man es denn einem Frenden absolut unmöglich machen, die Privaten daten zu verendern? Es steht privat davor, also weis er, dass es ihn nichts angeht.
-
Ben04 schrieb:
thordk schrieb:
deshalb sollte man auch lieber von sichtbarkeit und nicht "zugriffsrecht" sprechen.
Sichtbarkeit ist auch nicht gut, weil private Daten sind sichtbar! Zu mindest können sie andere Daten verdecken. Zum Beispiel:
struct Foo{ int foo; }; class Bar:public Foo{ private: int foo; }; int main(){ Bar bar; bar.foo = 4; // Bum }wieso sollte der private member dadurch sichtbar werden? wenn du über ein Bar objekt zugreifst, sagst du ganz eindeutig, dass du an den member foo von bar heranwillst und nicht den von foo. und der ist private und somit nicht sichtbar. um den von foo zu erreichen, müsstest du den zugriff qualifizieren.
-
Das Wort "sichtbar" ist hier IMO nicht angebracht, natürlich ist er "sichtbar". Der Zugriff ist bloss nicht erlaubt. Was soll daran "unsichtbar" sein? Wenn "Bar::foo" unsichtbar wäre, dann würde ich erwarten dass das Beispiel compiliert, was es nicht tut, da "Bar::foo" eben "sichtbar" ist, daher ausgewählt wird, der Zugriff aber nicht erlaubt ist, und daher der Compiler richtigerweise schreit.
BTW:
bar.Foo::foo = 4; // so geht's@Fellar:
Deine Überlegungen sind typisch für Leute die mit C++ anfangen, ich hab mir das selbst vor Jahren auch mal überlegt. Letztendlich ist es aber vollkommen egal was wer wo machen könnte wenn er deine Header Files editiert. Wenn er das macht ist ER dafür verantwortlich wenn was nicht funktioniert.Wenn du Informationen/Daten/Funktionen/... wirklich *verstecken* willst musst du deine Klassen "pimpln" (pimpl pattern), und die Library/DLL dann vorkompiliert mit nur .lib/.dll/.h Files ausliefern.
Natürlich ist selbst das kein 100%iger Schutz, da man alles irgendwie disassembliert bekommt.Im Allgemeinen sollte man sich darüber aber einfach keinen Kopf machen, und Dinge so programmieren wie sie Sinn machen, und sich nicht weiter den Kopf darüber zerbrechen was wer wo machen könnte wenn er die Header Files editiert.
Natürlich will ich als Entwickler mir nicht in die Karten schauen lassen, deswegen ist mGeheimerText auch private
Je mehr man von fremdem Code mit dem man arbeiten muss (andere Module, LIBs, DLLs etc.) sehen kann, je einfacher deiser zu durschauen ist, desto besser für alle. Z.B. schonmal deswegen weil fast nichts jemals fehlerfrei ist, und auch fast nichts jemals so gut dokumentiert ist dass keine Fragen auftreten. Je mehr man "in die Karten schauen" kann, desto schneller wird man seine Fragen beantwortet finden oder ggf. Fehler in dem fremden Code auffinden. Beantwortete Fragen sind gut, und gefundene Fehler kann man reparieren -> alle sind glücklich
