Forum: PC-Programmierung C++ - Problem mit protected


von Johannes (Gast)


Lesenswert?

Hallo Leute!

Ich habe eine Frage zu C++ zur Vererbung von Klassen.
Hier ein Beispielcode, den ich gerade programmiert habe. Leider tritt 
bei mir in VC++ der Fehler "C2248" auf

"Kein Zugriff auf protected Member, dessen Deklaration in der 
Eltern-Klasse erfolgte."


Ich möchte, dass ich von der Klasse "Sohn" NICHT auf das Attribut 
"erziehen" zugreifen kann, da ein "Sohn" nicht erziehen darf.


Hier der Code
1
/********    Vererbung 1 : Einfache Vererbung von zwei Klassen *******/
2
3
4
#include <iostream>
5
6
using namespace std;
7
8
/*********** Elternklasse ************/
9
10
class Eltern
11
{
12
private:
13
    
14
public:
15
  char F_or_M;                        // Männlich oder weiblich? Eines der beiden ist wohl auch der Sohn.                                          
16
  int AnzahlKinder;                      //...der Sohn darf noch keine Kinder haben
17
                                
18
19
protected:
20
  bool erziehen;                        //...denn das können nur die Eltern
21
22
};
23
24
/*********** Kindklasse *************/
25
26
class Sohn : public Eltern
27
{                                //...alle Attribute, die bei "Eltern" nicht in protected stehen werden hierher vererbt
28
public:
29
  int Note_in_Programmieren;                  // Schulnoten kriegt nur der Sohn.
30
  bool heimliche_freundin;                  // Heimliche Freundin hat auch nur der Sohn.
31
};
32
33
34
35
/****************************** MAIN-Funktion   ****************************/
36
37
38
39
int main (void)
40
{
41
  Eltern Mutti;
42
  Mutti.F_or_M = 'f';                    // Mutti ist weiblich
43
  Mutti.erziehen = true;                  // sie erzieht auch noch.
44
45
  Sohn Johannes;                      // Objekt "Johannes" anlegen
46
  Johannes.Note_in_Programmieren = 675;            
47
  Johannes.heimliche_freundin = true;          
48
  
49
50
51
  cout << Johannes.Note_in_Programmieren << endl;
52
53
  system("pause");
54
  return 0;
55
}


Wo liegt mein Fehler?


Vielen Dank schon mal!

Gruß
Joh.

von Peter (Gast)


Lesenswert?

kann es sein das es irgenwie verkehrt rum ist? Warum fängst du nicht bei 
einer person an und leidest davon den Sohn und dann die Eltern ab. Warum 
ist der Sohn von den Eltern abgeleiter, das macht doch überhaupt kein 
sinn.

Das Protekt wirkt sich innerhalb der Objekte aus. Die greifst sogar von 
ausen auf dem member zu, dafür sollte man Set und Get Methoden 
schreiben. Wenn ein member protected sagt aus das das Member nur in 
einer abgeleitet klasse verwendet werden darf aber nicht von aussen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Du versuchst, von main aus auf das protected Element erziehen von
Mutti zuzugreifen. Das geht nicht. Du könntest aber von main aus
eine public-Methode von Mutti aufrufen, die erziehen auf true setzt.

von Johannes (Gast)


Lesenswert?

@Peter:

Es soll ja genau diesen Zusammenhang verdeutlichen. Dass sich der Sohn 
von den Eltern "ableitet", sprich, Eigenschaften der Eltern erbt, jedoch 
nicht alle.

Dass man normalerweise set- und get-Funktionen schreibt, um auf die 
Attribute (aus Sicherheitsgründen) nicht direkt zugreifen zu können, ist 
mir klar. Dennoch möchte ich ohne set-/getFunktionen die Attribute von 
Eltern- und Sohn folgendermaßen setzen, wie es in den Kommentaren steht.

Warum funktioniert das nun nicht?

von Johannes (Gast)


Lesenswert?

@Yalu X.:

Deine Aussage wäre für mich plauibel, wenn "bool erziehen" in private 
von "Eltern" und NICHT in public von "Eltern" stünde.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Johannes schrieb:
> Deine Aussage wäre für mich plauibel, wenn "bool erziehen" in private
> von "Eltern" und NICHT in public von "Eltern" stünde.

erziehen steht eben nicht in public von Eltern sondern in
protected. Und protected ist außerhalb der Klasse genauso wenig sichtbar
wie private.

von Johannes (Gast)


Lesenswert?

ok.

Und wie kann ich dann "bool erziehen" nur vom Objekt der Klasse "Eltern" 
sichtbar machen?

von DerAlbi (Gast)


Lesenswert?

Die Funktionalität die du suchst gibt es nicht.
Entweder
a) privat, dann darf NUR die klasse und deren Methoden drauf zugreifen,
b) pulic, dann darf jeder
c) protected dann darf auch eine abgeleitete klasse darauf zugreifen, 
ansonsten verhält sich das wie private.

Du suchst: "machs für alle sichbar außer für abgeleitete klassen" Das 
ist unfug bzw ein konzeptfehler. Das bekommst du nur mit einer anderen 
ableitungshierarchie hin.

von Martin (Gast)


Lesenswert?

Johannes schrieb:
> Es soll ja genau diesen Zusammenhang verdeutlichen. Dass sich der Sohn
> von den Eltern "ableitet", sprich, Eigenschaften der Eltern erbt, jedoch
> nicht alle.

Das ist nicht das, was die Vererbungsrelation in C++ ausdrückt.

Daher wirst du mit dem Ansatz, "Sohn" von "Eltern" abzuleiten, immer und 
an allen Stellen immense Schmerzen haben.

von U.R. Schmitt (Gast)


Lesenswert?

Hallo Johannes,

hör auf das was Martin schreibt.
Vererbung bei OO Programmierung hat nur bedingt mit biologischer Eltern 
Kind Beziehung zu tun, auch wenn der Begriff daher abgeleitet ist.
Es hat mehr damit zu tun daß du allgemeinere Eigenschaften in Eltern 
(übergeordneten) Klassen ablegst, und spezifische dann in den Kind 
Klassen.

Ein nettes Beispiel ist

Fahrzeug
2-Rad : Fahrzeug
4-Rad : Fahrzeug
Fahrrad : 2-Rad
Auto: 4-Rad
PKW : Auto
LKW : Auto

jedes Fahrzeug hat z.B. die Methode beschleunigen(), bremsen(), lenken() 
und parken(), oder aquch die Variable Eigentümer.
Die Implementierung ob man jetzt bei einem Fahrrad beide Handbremsen 
ziehen muss zum Bremsen oder im PKW das Bremspedal treten, ist in den 
Klassen ggf. völlig unterschiedlich implementiert (Überladen, bzw. 
abstrakt in der Elternklasse definiert).
Wenn man aber ein Fahrzeug zum Fahren benutzen will, kann man jetzt 
unabhängig was für ein Fahrzeug man hat, die Methoden zum beschleunigen, 
bremsen, lenken usw. benutzen, ohne die innere Implementierung genau 
kennen zu müssen.

von besucher (Gast)


Lesenswert?

@Johannes: Das Problem liegt hier:

class Sohn : public Eltern

Die Vererbung drückt eine "Ist-ein"-Relation aus, es wird also 
behauptet: "Ein Sohn ist ein Eltern-(teil)", und hat deshalb ALLE 
Eigenschaften von Eltern, plus einige besondere, die nur er selbst hat.

Da das in der Realität nicht so ist, ist der Modellansatz falsch und du 
hast die beschriebenen Probleme.

Folgender Ansatz könnte in dieser Hinsicht besser sein:
1
class Mensch // Basisklasse für Kind und Eltern
2
{
3
protected:
4
5
    std::string name;
6
    
7
};
8
9
class Eltern : public Mensch
10
{
11
    std::list<Kind &> kinder; // Container für 0 bis N Kinder
12
};
13
14
class Kind : public Mensch
15
{
16
    Eltern & vater;    // genau ein Vater
17
    Eltern & mutter;   // genau eine Mutter
18
};

Wobei auch das nicht der Weisheit letzter Schluss ist, denn was 
passiert, wenn aus Kindern Eltern werden? Und Kinder sind sie trotzdem 
noch. Vielleicht muss man das anders lösen als mit Ableitung.

von Karl H. (kbuchegg)


Lesenswert?

besucher schrieb:

> Wobei auch das nicht der Weisheit letzter Schluss ist, denn was
> passiert, wenn aus Kindern Eltern werden? Und Kinder sind sie trotzdem
> noch. Vielleicht muss man das anders lösen als mit Ableitung.

Muss man.
Ob jemand Eltern oder Kind ist, ist eine Frage des Objekts und nicht der 
Klasse. Hier wird versucht etwas in eine Klassenstruktur zu quetschen, 
was da so nicht hineingehört. Die Eltern-Kind Beziehung ergibt sich aus 
dem dynamischen Zusammenhang, welche Mensch bei einem anderen Menschen 
als Vater oder Mutter eingetragen ist, bzw. welche Personen bei einem 
anderen Menschen als Kind eingetragen ist.

Aber jeder Mensch hat erstmal einen Vater UND eine Mutter UND Kinder. 
Wobei natürlich es auch den Fall geben kann, dass man sie nicht kennt.

Also so
1
class Mensch
2
{
3
  private:
4
5
    std::string        name;
6
7
    Mensch*            vater;
8
    Mensch*            mutter;
9
    std::list<Mensch*> kinder;
10
};

damit kann man jetzt alle Verwandschaftsbeziehungen ausdrücken und 
entsprechende Relationen erzeugen bzw abfragen.
Überlegt euch einfach mal, wie in einer starren Hierarchie wie weiter 
oben die Beziehungen "Ist Opa von", "Ist Oma von", "ist Tante von", "Ist 
Neffe von" auszudrücken wären. Es geht nicht.

Bei Klassenhierarchien muss man aufpassen, dass man die Dinge nicht 
übertreibt und sich ein zu starres Korsett anlegt, dass in weiterer 
Folge unflexibel ist. Weniger ist da oft mehr.
Im konkreten Fall ist "Vater sein", "Mutter sein", "Kind sein" eine 
Eigenschaft einer Person, die sich aus dem zusammenhang ergibt. Aber 
niemand kommt zur Welt und 'IST EINE' Mutter.

Für Klassen sollte man sich immer die Frage stellen: Wenn eine Klasse 
eine 'IST-EIN' Beziehung ausdrückt, gilt das dann für meinen Fall? 'IST' 
Herbert wirklich ein Kind oder ist er nicht in erster Linie Mensch, der 
nur dadurch zum Kind wird, dass er Vater und Mutter hat und dort jeweils 
als Kind eingetragen ist. D.h. die Eigenschaft 'Kind sein' ergibt sich 
aus dem Zusammenhang von mehreren Objekten, aber eine Person ist nicht 
eines aus der Typisierung Kind/Vater/Mutter.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.