Welchen Sinn hat das protected Privileg ??
-
Wozu genau brauche ich dieses privileg , irgendwie ist mir das nicht klar ...
Warum muss ich meinen Klassen die Veerben sagen , dass manche ihrer Member Variablen auch für die Unterklassen erreichbar sein sollen ...
Jede Unterklasse erbt doch generell Variablen vom selben Typ ...
Ich brauch vieleicht mal ein einfaches Beispiel ..
Danke .
-
class Base { private: int _priv; protected: int _prot; }; class Derived : public Base { public: void foo () { _prot = 5; // ok _priv = 5; // not ok } };MfG SideWinder
-
Die Klasse Derived besitzt doch selber auch die Membervariablen ..
_prot und _priv oder nicht ... und sollte deswegen doch keine Probleme habe darauf zu zugreifen.
Irgendwie bin ich verwirrt ...
-
Derived besitzt zwar in dem Sinne beide Variablen, als sie natürlich beiden in den Speicherbereichen ihrer Instanzen liegen, auf _priv kann sie aber nicht zugreifen. Da _priv in Base als private deklariert wurde, haben in Derived nur die geerbten Basismethoden darauf Zugriff.
Das macht im Hinblick auf die Kapselung sehr viel Sinn. Wenn du z.B. von string ableitest, weil dein neuer String ein paar tolle neue Methoden haben soll, darfst du natürlich nicht Zugriff auf den internen char-Pointer haben, da dieser vollständig von string gekapselt wird. Versehentliche oder unbewusst schädliche Änderungen daran können leicht Fehler produzieren und genau diese will man durch die Kapselung verhindern. Möchtest du Manipulationen vornehmen, musst du dazu die geerbten Methoden verwenden.
-
Bacid90210 schrieb:
Die Klasse Derived besitzt doch selber auch die Membervariablen ..
_prot und _priv oder nicht ... und sollte deswegen doch keine Probleme habe darauf zu zugreifen.
Irgendwie bin ich verwirrt ...
Es ist nicht so, dass es das Attribut 2x gibt (in Base und Derived), sondern Derived hat Zugriff auf das Attribut der Basisklasse.
Nun denkst du vielleicht, dass die Eigenschaft dann auch nicht vererbt wird, wenn es das Attribut in Derived gar nicht gibt.
... Doch es wird vererbt, weil wenn du ein Objekt der abgeleiteten Klasse erzeugst auch ein Objekt der Basisklasse erzeugt wird,
also in dem Objekt der abgeleiteten Klasse ein Objekt der Basisklasse steckt.Hoffe das hilft

-
Erbt meine abgeleitete Klasse denn nur public Variablen und Member Funktionen wenn ich sie public ableite.Und die privat Variablen die ich Vererben möchte muss ich als protected deklarieren damit meine Unterklassen zugriff darauf haben ich aber nicht möchte dass von außen darafu zugegriffen werden kann ...??
Habe ich das jetz richtig verstanden ...
-
wenn du mit public vererbst, dann kannst du innerhalb deiner abgeleiteten Klasse auf public und protected - Elemente der Elternklasse zugreifen. Von außen allerdings nur auf public - Elemente.
Wie du vererbst (public, protected, private) hat aber weniger Einfluss darauf, wie du aus deiner abgleiteten Klasse auf deine Elternklasse zugreifen kannst.
Vielmehr wird hier der Sichtbarkeitsbereich auf deine abgeleitete Klasse festgelegt.
-
Bacid90210 schrieb:
Erbt meine abgeleitete Klasse denn nur public Variablen und Member Funktionen wenn ich sie public ableite.Und die privat Variablen die ich Vererben möchte muss ich als protected deklarieren damit meine Unterklassen zugriff darauf haben ich aber nicht möchte dass von außen darafu zugegriffen werden kann ...??
Glaub noch nicht ganz. Mit der Art der Ableitung hat das nix zu tun. Damit steuerst du, wie von Außen ein Objekt deiner abgeleiteten Klasse ansprechbar ist. public-Vererbung bedeutet hier, dass alle public-Methoden der Basisklasse von außen errecihbar sind. protected-Vererbung würde den public-Bereich der Basisklasse nach protected schieben, das heißt nur von Derived abgeleitete Klassen können auf den public-Bereich von Base zugreifen. private-Vererbung schottet die Basis komplett ab.
friend weicht aber das ganze Konzept wieder auf.
Das protected in der Klasse ist jetzt speziell für den Vererbungsfall gedacht, um einen Bereich zu schaffen, der dem ordinären Nutzer verschlossen bleibt, der aber geschützten Zugriff auf spezielle Methoden(/Variablen) bietet, mit der die Basis kontrolliert werden kann.
-
Bacid90210 schrieb:
Erbt meine abgeleitete Klasse denn nur public Variablen und Member Funktionen wenn ich sie public ableite.Und die privat Variablen die ich Vererben möchte muss ich als protected deklarieren damit meine Unterklassen zugriff darauf haben ich aber nicht möchte dass von außen darafu zugegriffen werden kann ...??
Habe ich das jetz richtig verstanden ...Vererbt wird alles (da in einem Derived-Objekt immer ein Base-Objekt steckt).
Die Zugriffsmodifizierer spezifizieren lediglich,
ob die abgeleitete Klasse Zugriff darauf hat oder nicht.private: abgeleitete Klasse darf nicht darauf zugreifen.
protected: abgeleitete Klasse darf darauf zugreifen.
public: abgeleitete Klasse und jeder Andere (also auch von außen) darf darauf zugreifen.
[ EDIT ] ... falsch gelesen, es geht ja um die Art der Ableitung ...
Habe dir mal ein Beispiel dazu gemacht.
class Base { private: int i_private; protected: int i_protected; public: int i_public; }; class PrivateVererbung : private Base { /* In dieser Klasse gilt: i_protected und i_public werden private. */ }; class ProtectedVererbung : protected Base { /* In dieser Klasse gilt: i_protected bleibt protected. i_public wird protected. */ }; class PublicVererbung : public Base { /* An der Zugriffsspezifikation ändert sicht nichts: i_public bleibt public. i_protected bleibt protected. --> Man kann die Sichtbarkeit nie erweitern. */ }; class Test : public PrivateVererbung { /* Diese Klasse hat nun also kein Zugriff auf i_protected und i_public, da sie ja in der Klasse "PrivateVererbung" private sind. */ };
-
Es ist schon so spät und ich aknn eigentlich nicht mehr ..
Aber ich muss das jetzt verstehen ..
Vieleicht erkennt jemand meinen Denkfehler ..So denke ich :
class Base { private: int _priv; protected: int _prot; }; class Derived : public Base // DIESE KLASSE ERBT ALSO ALLE MEMBER { private : int _priv; //GEERBT protected: int _prot; //GEERBT public: void foo () { _prot = 5; // ok _priv = 5; // DANN MÜSSTE DAS DOCH AUCH OK SEIN ICH GREIFE DOCH //INNERHALB DER ABGEL. KLASSE DARAUF ZU .. } };
-
public: void foo () { _prot = 5; // ok _priv = 5; // DANN MÜSSTE DAS DOCH AUCH OK SEIN ICH GREIFE DOCH //INNERHALB DER ABGEL. KLASSE DARAUF ZU .. } };Nein, da dir Base EXPLIZIT verbietet darauf zuzugreifen - das ist eben das private! Auf private-Member haben nur Instanzen dieser Klasse selber und alle friends Zugriff.
-
ich glaub deine Eltern hätten was dagegen, wenn du auf ihre privaten Finanzen zurückgreifst nur weil du von ihnen "abgeleitet" bist.
-
Etwa gleicher Sachverhalt wie:
Base b; // b hat alle Member von Base b._priv = 5; // Oh, wiso geht das nicht?Die Member sind natürlich da, aber der Zugriff ist gesperrt.
-
Ok ich glaube ich habs jetz , wenn ich als möchte dass meine geerbeten private Member von mir verändert werden dürfen , muss meine Oberklasse sie als protected deklarieren .
Wenn ich dann also erbe ohne protected Privilegien zu nutzen ...
Kann ich die Member Variablen ja nach dem Initialsieren über den Konstruktor nicht mehr bearbeiten.
-
Bacid90210 schrieb:
Wenn ich dann also erbe ohne protected Privilegien zu nutzen ...
Kann ich die Member Variablen ja nach dem Initialsieren über den Konstruktor nicht mehr bearbeiten.Kommt darauf an. Du kannst in der abgeleiteten Klasse natürlich ebenso öffentliche Funktionen der Basisklasse aufrufen und so evtl. private Member verändern lassen. protected benötigt man nicht besonders oft, da die benötigte Funktionalität der Basisklasse idealerweise über das öffentliche Interface verfügbar ist und die privaten Member von diesen Funktionen angemessen verwaltet werden.
BasicMan01 schrieb:
ich glaub deine Eltern hätten was dagegen, wenn du auf ihre privaten Finanzen zurückgreifst nur weil du von ihnen "abgeleitet" bist.
Das Beispiel ist gar nicht so schlecht

-
Ok ..
Klasse B welche von Klasse A erbt kann die private Member also nur mit Elemtfunktionen der Oberklasse A ändern .
Kennzeichne ich die Member der Oberklasse als protected , kann meine Unterklasse aber auch mit den eigenen Funktionen daran herum scharauben , von außen habe ich aber keinerlei Zugriff ...So ..jetz ist es aber richtig formuliert

-
Bacid90210 schrieb:
Klasse B welche von Klasse A erbt kann die private Member also nur mit Elemtfunktionen der Oberklasse A ändern .
Sofern diese Funktion auch wieder mindestens protected oder public ist.
Aber ansonsten geht deine Formulierung durch. Generell würde ich aber die Abhängigkeit auch in einer Vererbung möglichst gering halten (und überlege mir daher gut, bevor ich eine Variable oder Funktion protected oder public mache). Um so weniger Kopplungen existieren, um so eher kann man eine Klassenhirachie nachträglich ändern (und dann sind Elementfunktionen den Variablenzugriffen in der Regel vorzuziehen, da man Funktionen leichter ändern kann, ohne den Code groß umzuschreiben).
-

ehrlich gesagt fallen mir kaum Anwendungsfaelle ein, bei denen es keine Alternative zu protected gegeben haette, oder wo protected Zugriff mir irgendeinen Vorteil gebracht haette, ausser um "mal schnell" was zu prototypen.
-
TheBigW schrieb:
ehrlich gesagt fallen mir kaum Anwendungsfaelle ein, bei denen es keine Alternative zu protected gegeben haette, oder wo protected Zugriff mir irgendeinen Vorteil gebracht haette, ausser um "mal schnell" was zu prototypen.
Protected-Variablen habe ich zwar fast nie, aber für Funktionen fallen mir schon ein paar Anwendungsfälle ein. Alternativen gibt es natürlich immer, aber die sind oft umständlicher, weniger elegant oder haben andere Nachteile.
Wenn eine Klasse den Memberzugriff auf abgeleitete Klassen beschränken will, was ist daran grundsätzlich falsch? Oder anders gefragt: Was würdest du in folgenden Situationen tun?
- Du hast eine überschriebene, nicht-öffentliche Methode (virtuell oder nicht) und willst die Basisklassenversion aufrufen. Zum Beispiel:
void Derived::Render() { Base::Render() // Zeichne restliche Teile dieser Instanz }- Du willst eine Basisklasse etwas fragen. Ich hatte kürzlich einen Fall im Zusammenhang mit
mutableund verzögerten Berechnungen:
bool Base::NeedsXYUpdate(); void Derived::DoSomething() { if (NeedsXYUpdate()) // ... }- Du willst, dass man eine nicht-polymorphe Klasse nicht direkt instanziieren kann, sondern nur über abgeleitete Klassen, und deklarierst die Konstruktoren der Basisklasse
protected. - ...
-
hast recht: ich hab mehr in Richtung Variablen - Zugriff gedacht. Fuer funktionen mag es schon Anwednugsfaelle geben (wie von Dir gezeigt).
Aber oft ist dann die Frage berechtigt warum die Funktion nicht gleich public sein darf (zumal jeder sowieso nach Ableitung public zugriff haben kann) - kommt natuerlich auf den Anwendungsfall an....