Frage zu Zugriffsrechten bei Objekten
-
Stell dir die Klasse als Einheit vor, die in sich zunächst komplett geschlossen ist.
Mit public kannst du diese Verschlossenheit aufheben.
class A { public: int x; }; // ... A a; a.x = 10;Würde gehen. Mit private funktioniert das nicht mehr. Der Sinn? Kapselung der Daten.
Die Klasse selber hat aber unabhängig von public und private Zugriff auf die Variable. Denn sie gehört ihr ja sozusagen.
-
// <-- auch wenn das public ist funktioniert es ...
Natürlich! Das Problem ist nur, dass ein Verändern von Außen ohne irgendwelche Überprüfungen die Gültigkeit des Objekts zerstören kann!
Zum Beispiel die "Angle"-Klasse. Nehmen wir an, sie bildet einen Winkel auf einen Kreis ab, der Wert muss also in den Bereich 0-360°. Wird ein neuer Wert gesetzt (über eine entsprechende setter-Methode), wird dieser in diesen Bereich "gemapped": 720°==360°==0°, 410°==50°, usw.
Die Methoden VERTRAUEN darauf, dass der intern gespeicherte Wert in diesen Grenzen liegt, wäre ja auch doof, wenn ich bei jeder noch so kleinen Berechnung erst eine entsprechende Prüfung einbauen müsste!
Nun stell dir vor, der interne Wert ist public, und $EVIL_USER kommt her und macht das:Angle a; a.value = 960;Juppidu, unsere geforderte Eigenschaft von 0<=value<360 ist ungültig! Darum machen wir "value" private, damit solche Sachen unter der Kontrolle der Klasse bleiben.
Ist das jetzt klarer?
-
obj schrieb:
float m_angle; // <-- auch wenn das public ist funktioniert es ...Klar funktioniert es. Nun stell Dir vor,
m_anglewäre public. Jetzt gibt es einen faulen Benutzer der Klasse, der direkt aufm_anglezugreift (es geht ja und spart Tipperei). In seiner Version wird inm_angleder Winkel in Grad gespeichert.Er legt das Objekt so an:
AngleClass a(180); // m_angle hat den Wert 180Nun greift er munter auf
m_anglezu (am Besten an vielen Stellen im Code, über viele Dateien verteilt):functionOfTheStupidUser(a.m_angle); //erwartet Winkel in Grad, also den Wert 180Jetzt denkt sich der Entwickler von
AngleClass(also eine andere Person), hey, wenn ich intern mit Radiant anstatt mit Grad rechne, ist die Klasse viel effizienter und der Code wird einfacher. Er ändert also entsprechend.Beim doofen Benutzer:
functionOfTheStupidUser(a.m_angle); //erwartet Winkel in Grad, jetzt sind es aber Radiant, also der Wert pi -> die Funktion macht MistJetzt muss man erstmal merken, dass etwas nicht stimmt und woher das Problem kommt. Wenn man Pech hat, ist schon ein Flugzeug abgestürzt.
Hätte der doofe, faule Benutzer die getter Funktion
AngleClass::getAngleDeg()benutzt, würde jetzt immer noch der Wert 180 an die FunktionfunctionOfTheStupidUserübergeben werden. Völlig unabhängig von der internen Darstellung.
Durch private verbietest Du nun, das Anwender auf der internen Darstellung rumhampeln. Diese müssen brav die Getter und Setter benutzen, und bei denen kannst Du (als Entwickler der Klasse) sicherstellen, dass immer das richtige herauskommt. Unabhängig davon, was intern passiert.
-
Hi,
also ich finde das ganz einfach:
- Jeder (naja - fast) darf mir die Hand geben
- Nur MEINE Hand darf meinen Dödel anfassen (oder andere Körperteile, dmit denen es mir möglich ist).Diese Trennung finde ich gut. ... und ich sehe keinen Grund dafür, meiner Hand den Zugriff auf meinen Dödel prinzipiell zu verbieten.

Gruß,
Simon2.
-
Simon2 schrieb:
...
ROFL ... you made my day

-
Die "friends" dürfen das auch ...

-
padreigh schrieb:
Simon2 schrieb:
...
ROFL ... you made my day

Das ist eine Übersetzung aus dem Englischen, im Original wird es noch deutlicher:
Only you and your friends may touch your private parts.
Neither your children nor your friends' children may not touch your privates.
-
Ok das mit dem Private hab ich verstanden.
Aber es ging mir um das objekt w was in CopyData steht: w.CopyData( w);
Das ich da in diesem Beispiel keinen Sinn sehe.
Das man die Variable width im Hauptprogramm z.b. nciht so ändern kann das hab ich verstanden; main () { Window w; w.width = 100; } <-- Geht ja nicht weil width Private ist.
#include <iostream> using namespace std; class Window { short width; public: int CopyData( Window& source ); Window :: Window () { width = 2; } }; int Window::CopyData( Window &source) { width = source.width; cout<< source.width << endl;; cout<< width << endl; } int main () { Window w; w.CopyData( w); system("PAUSE"); }
-
Weil sich die Zugriffsrechte eben nicht auf das einzelne Objekt beschränken, sondern für die Klasse gelten. Sonst wäre so etwas wie ein Kopierkonstruktor oder operator= gar nicht möglich!
class Klasse { State state; // hierfür gibt es keinen getter oder setter, das ist nur eine intern genutzte Variable public: Klasse(const Klasse& other); // Und wie sollen wir hier vorgehen, wenn state auch kopiert werden können soll? };Die Klasse "Window" hat ja auch "CopyData" im Griff, kann damit aufpassen dass nichts schlechtes geschieht.
-
SeppJ schrieb:
...
Only you and your friends may touch your private parts.
Neither your children nor your friends' children may not touch your privates.

Das finde ich gut (und auch besser als meins) - kannte ich allerdings nicht.
(obwohl mir natürlich der Ausdruck "my private( part)s" schon bewusst war).Mir war allerdings hier im Kontext wichtig, dass überhaupt die eigenen public Funktionen auf die "privates" zugreifen dürfen. Das war hier ja IMHO die Verständnisschwierigkeit des Fragestellers...
padreigh schrieb:
Simon2 schrieb:
...
ROFL ... you made my day

Gern geschehen.

Danke,
Simon2.
-
SeppJ schrieb:
Only you and your friends may touch your private parts.
Neither your children nor your friends' children maynottouch your privates.Ist das da nicht ein 'not' zu viel?