Forum: PC-Programmierung C++ Vererbung => eines ist mir schleierhaft


von Maude (Gast)


Lesenswert?

Hallo Gemeinde,

eines gibt mit bei der Vererbung bei C++ zu grübeln (vll. ist das auch 
in Sprachen so - weiß ich nicht).

Szenario:
Es gibt eine Basisklasse "Base" in der einige Methoden und 
Membervariablen definiert sind.

Es gibt eine Klasse, die davon über "public" erbt - "UseMe".

In UseMe komme ich nur an "Base" Membervaiablen dran, die Public sind. 
Wiso ist das nicht so, dass "UseMe" in Kopie alles von "Base" übernimmt. 
Also die in "Base" als private deklarierten Member als eigene private 
Member hat.

Was mich daran stört ist, wenn ich die Member in "Base" public mache, 
kann ich die auch außerhalb von "UseMe" sehen.

Wiso ist es auf diese Art gelöst?

: Verschoben durch User
von Oliver S. (oliverso)


Lesenswert?


von Thomas W. (thomas100)


Lesenswert?

Wie wäre es einfach mit "protected"?
Dann ist deine Membervariable in der Basisklasse und in den abgeleiteten 
Klassen sichtbar.

VG
Thomas

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

In der objektorientierten Programmierung ist es ein weit verbreitetes 
Pattern, so wenig wie möglich zu exponieren.

Der Nutzen wird besonders offensichtlich, wenn die Basisklasse von 
jemand anderem Entwickelt wurde, als die Kind Klasse.

Wenn der Lieferant der Bassisklasse etwas verändern möchte, muss er 
lediglich darauf achten, dass die exponierten Sachen (public und 
protected) kompatibel bleiben. Alle anderen Teile sind quasi 
Betriebsgeheimnis und können verändert werden, ohne dass es den Benutzer 
der Basisklasse tangiert.

Als praktisches Beispiel schau Dir mal Windows an. Die allermeisten 
Programme, die für Windows 95 entwicklet wurden, laufen auch auf allen 
neueren Windows Versionen. Das geht nur deswegen, weil Microsoft den 
Größten Teil des Betriebsystems als private behandelt und nur wenige 
ausgewählte Felder und Methoden exponiert.

Wenn hingegen alles public wäre, dann würden die meisten Windows 
Programme nur mit der Windows Version funktionieren, mit der sie 
entwickelt wurden.

von Mork vom Ork (Gast)


Lesenswert?

Oliver S. (oliverso) schrieb:

Maude schrieb:
>> Wiso ist es auf diese Art gelöst?

> Ist es nicht.

> http://de.wikibooks.org/wiki/C%2B%2B-Programmierung:_Klassen#Zugriffskontrolle

aus dem Link

class EineKlasse
{
  public:
    int liesGeheimnis() const;

  protected:
    void bestimmeGeheimnis(int Wert);

  private:
    int geheimnis;

  friend class AndereKlasse;
};

Was ist denn das???

    int liesGeheimnis() const;
                      ---------

Ein nachgeschobenes Constant für was???

Mal wieder ein C++ Geheimnis das nur eingeweihte verstehen?

von Dr. Sommer (Gast)


Lesenswert?

Mork vom Ork schrieb:
> Mal wieder ein C++ Geheimnis das nur eingeweihte verstehen?
Soll das ein Witz sein? Das steht in jedem C++ Buch. Man muss die 
Sprache schon kennen die man verwendet.
http://stackoverflow.com/questions/751681/meaning-of-const-last-in-a-c-method-declaration

von Mork vom Ork (Gast)


Lesenswert?

Dr. Sommer (Gast) schrieb:

> Soll das ein Witz sein? Das steht in jedem C++ Buch. Man muss die
> Sprache schon kennen die man verwendet.

Nein, das ist kein Witz. Ich bin nun mal mehr im C zuhause und dort gibt 
es eine Funktion, einen Funktionsparameter und einen 
Funktionsrückgabewert.

Wozu braucht man denn solche schrägen Konstruktionen überhaupt? Dein 
Link zeigt doch auf was das nach sich zieht

" What is the meaning of const in declarations like these? The const 
confuses me. "

Aha!

" When you add the const keyword to a method the this pointer will 
become const, and you can therefore not change any member code. (Unless 
you use mutable, more on that later).

The const keyword is part of the functions signature which means that 
you can implement two similar methods, one which is called when the 
object is const, and one that isn't. "

Na "toll", "gut" das es das gibt. Räusper!

Ohne wäre die Welt wahrscheinlich untergegangen.

Hauptsache so verwirrend und kompliziert wie möglich. Einfach wäre ja zu 
viel verlangt.

von Dr. Sommer (Gast)


Lesenswert?

Mork vom Ork schrieb:
> Ich bin nun mal mehr im C zuhause und dort gibt
> es eine Funktion, einen Funktionsparameter und einen
> Funktionsrückgabewert.
Ja. Aber Paramter können auch da "const" sein. Da das "this" in C++ kein 
expliziter Parameter ist, wird das eben durch das nachgestellte "const" 
auf konstant gesetzt. Wenn du kein C++ kannst, solltest du dich mit "Mal 
wieder ein C++ Geheimnis das nur eingeweihte verstehen?" zurückhalten 
und einfach nett fragen. Oder googlen.

Mork vom Ork schrieb:
> Ohne wäre die Welt wahrscheinlich untergegangen.
Ja, ohne könnte man keine const-Korrektheit umsetzen.

Mork vom Ork schrieb:
> Hauptsache so verwirrend und kompliziert wie möglich. Einfach wäre ja zu
> viel verlangt.
Was ist denn daran kompliziert? Wie hättest du es denn gemacht, lieber 
"c" statt "const" weil kürzer und einfacher?

von Mork vom Ork (Gast)


Lesenswert?

Dr. Sommer (Gast) schrieb:

> Da das "this" in C++ kein
> expliziter Parameter ist, wird das eben durch das nachgestellte "const"
> auf konstant gesetzt.

Das genau ist (mal wieder) das Problem dieser Sprache. Es gibt irgendwo 
im unsichtbaren Cpp-Dickicht einen impliziten, getarnten this Parameter 
und nun taucht plötzlich völlig unerwartet ein explizites Schlüsselwort 
"const" an einer Stelle auf, die einem nicht sofort einleuchtet (eben 
weil sie sich auf etwas unsichtbares bezieht) und entfaltet dort eine 
Bedeutung, die gleichzeitig wieder durch ein anderes Schlüsselwort 
(mutable) zunichte gemacht werden kann.

Na toll!

Mir ist schon klar, dass du das alles locker aus der Hosentasche 
erklären kannst. Aus leidiger Erfahrung hierzu ein Satz

Diskutiere niemals mit einem C++ Kenner, denn er zieht dich auf sein 
Niveau herunter, schlägt dich (locker) mit seiner Erfahrung und lässt 
dich dabei blöd aussehen.

> Wie hättest du es denn gemacht

Wie haben es andere Sprachen denn gemacht, die ohne sowas auskommen? Die 
müssen ja furchtbare Defizite haben.

Übrigens Danke für deine Antwort (ernst gemeint)! Denn nicht, dass du 
mich falsch verstehst. Aber ich stelle mir nur allzu gerne die Sinnfrage 
bei solchen Spezialitäten. Mir kommt sowas wie hier immer vor als wenn 
mir das liebe Marketing allen möglichen überflüssigen Schnickschnack, 
der mal für Sonderfälle erdacht wurde, nun für allgemein unverzichtbar 
anpreisen will und mir dann erklärt, wie rückwärtsgewandt und blöde ich 
sei, weil ich nicht gewillt bin das auf Anhieb einzusehen.

Ich hatte bloß spontan (mal wieder) das Gefühl wie öfter beispielsweise 
bei LTSpice, spontan einem Bunch von undurchschaubaren Parametern 
gegenüber zu stehen, die nur Helmut aufdröseln kann, weil F1 mich da zum 
Such-Affen werden lässt. Natürlich hätte ich hier gockeln oder in die 
C++  Schwarte schauen können und gewiss, die könnten mir so ziemlich 
jedes Konstrukt dort als Weltneuheit - wie ein Dyson-Vertreter seine 
1.000.000 Upm LuftZwirbelDrüse - schlau und bedeutungsvoll beschreiben 
und mich dabei alt aussehen lassen.

C++ ist aber gerade nur beiläufig mein Thema. Du siehst, grundsätzlich 
interessiert bin ich durchaus (allerdings eher in der Breite und nicht 
nur auf C++ und das macht die Lage ein wenig schwierig).

von Dr. Sommer (Gast)


Lesenswert?

Mork vom Ork schrieb:
> Das genau ist (mal wieder) das Problem dieser Sprache. Es gibt irgendwo
> im unsichtbaren Cpp-Dickicht einen impliziten, getarnten this Parameter
Wenn du implizite Dinge nicht magst, solltest du ausschließlich 
Assembler verwenden. Den impliziten this-Pointer gibts in allen 
OOP-Sprachen, auch C++. Er vereinfacht die Programmierung und schont 
Tastaturen.

Mork vom Ork schrieb:
> die einem nicht sofort einleuchtet (eben
> weil sie sich auf etwas unsichtbares bezieht)
Aber Pointer-Arithmetik und Dreifach-Pointer in C sind einleuchtend? Wie 
gesagt, man muss seine Sprache schon kennen...

Mork vom Ork schrieb:
> Diskutiere niemals mit einem C++ Kenner, denn er zieht dich auf sein
> Niveau herunter, schlägt dich (locker) mit seiner Erfahrung und lässt
> dich dabei blöd aussehen.
Oi. Für das Stammtisch-Niveau haben wir hier doch schon genug "C++ 
Threads".

Mork vom Ork schrieb:
> Wie haben es andere Sprachen denn gemacht, die ohne sowas auskommen? Die
> müssen ja furchtbare Defizite haben.
Ja, haben sie. Java hat's nicht, und daher auch keine const-Korrektheit 
- erschwert die Fehlersuche.

Mork vom Ork schrieb:
> Mir kommt sowas wie hier immer vor als wenn
> mir das liebe Marketing allen möglichen überflüssigen Schnickschnack,
Dieser Schnickschnack hilft dabei, Fehler schon beim Compilieren und 
nicht erst im 918273. Unit-Test zu finden. Viele Programmierer sehen das 
als hilfreich an.

Mork vom Ork schrieb:
> Natürlich hätte ich hier gockeln oder in die
> C++  Schwarte schauen
Ja, das musst du. C++ ist eine der komplexesten Sprachen, die lernt man 
nicht vom hingucken.

Mork vom Ork schrieb:
> die könnten mir so ziemlich
> jedes Konstrukt dort als Weltneuheit
Du musst es ja nicht verwenden. Viele Sprachen verzichten ja sogar auf 
Typsicherheit. Aber das hat andere Probleme - als ich ein mal ein 
größeres Projekt in ruby (dynamisch typisiert) umgesetzt habe und durch 
100 Klassen und Dateien irgendwo einen falschen Parameter suchen musste, 
sehnte ich mich zurück nach C++, das diesen Fehler sofort beim 
compilieren gefunden hätte!

von Dr. Sommer (Gast)


Lesenswert?

PS: C++ hat noch eine Menge mehr schöne Dinge als nur versteckte 
this-Pointer und "const" zu bieten. Wenn du bei jedem so einen Aufstand 
machst ob man das wirklich braucht und ob das zu implizit ist, kommst du 
da nicht weit...

von Rolf M. (rmagnus)


Lesenswert?

Mork vom Ork schrieb:
> Das genau ist (mal wieder) das Problem dieser Sprache. Es gibt irgendwo
> im unsichtbaren Cpp-Dickicht einen impliziten, getarnten this Parameter
> und nun taucht plötzlich völlig unerwartet ein explizites Schlüsselwort
> "const" an einer Stelle auf, die einem nicht sofort einleuchtet (eben
> weil sie sich auf etwas unsichtbares bezieht) und entfaltet dort eine
> Bedeutung, die gleichzeitig wieder durch ein anderes Schlüsselwort
> (mutable) zunichte gemacht werden kann.

Wenn du die Sprache nicht richtig lernst, sondern einfach irgendwo ein 
Beispiel rausklaubst, das du nicht verstehst, ist es kein Wunder, daß 
Dinge für dich unerwartet sind. Das würde dir in jeder Sprache so gehen.

> Na toll!

Bevor du die Sinnhaftigkeit bestimmter Konstrukte anzweifelst, 
solltest du vielleicht erstmal wenigstens versuchen, sie zu verstehen, 
statt gleich als erstes relflexartig zu schimpfen.

> Diskutiere niemals mit einem C++ Kenner, denn er zieht dich auf sein
> Niveau herunter, schlägt dich (locker) mit seiner Erfahrung und lässt
> dich dabei blöd aussehen.

Das ist aber schon eine arg verzerrte Wahrnehmung. Was erwartest du 
denn, wenn du hier im Stil von "na toll, alles Mist, wozu dieser 
Quatsch" reinplatzt? Wie man in den Wald reinruft...

>> Wie hättest du es denn gemacht
>
> Wie haben es andere Sprachen denn gemacht, die ohne sowas auskommen? Die
> müssen ja furchtbare Defizite haben.

Warum müssen sie das? Die sind halt anders. Überraschung: Verschiedene 
Programmiersprachen handhaben manche Sachen unterschiedlich. Kann es 
deiner Meinung nach nur die zwei Varianten geben, daß ein Sprachfeature 
entweder komplett sinnlos ist oder in allen Sprachen zwingend 
erforderlich?

> Übrigens Danke für deine Antwort (ernst gemeint)! Denn nicht, dass du
> mich falsch verstehst. Aber ich stelle mir nur allzu gerne die Sinnfrage
> bei solchen Spezialitäten.

Dagegen ist nichts einzuwenden, aber dazu solltest du erstmal die 
Hintergründe kennen. Erst danach kannst du fundiert sagen, ob es deiner 
Meinung nach sinnvoll ist oder nicht. Aber nur weil ein const an einer 
Stelle auftaucht, an der du es nicht erwartest, gleich mal drüber zu 
schimpfen, bringt nichts.

> C++ ist aber gerade nur beiläufig mein Thema. Du siehst, grundsätzlich
> interessiert bin ich durchaus (allerdings eher in der Breite und nicht
> nur auf C++ und das macht die Lage ein wenig schwierig).

C++ ist eine komplizierte Sprache. Das macht es natürlich schwierig, sie 
zu verstehen, wenn man sich nur beiläufig drum kümmert.

von Mork vom Ork (Gast)


Lesenswert?

Rolf Magnus (rmagnus) schrieb:

>> Übrigens Danke für deine Antwort (ernst gemeint)! Denn nicht, dass du
>> mich falsch verstehst. Aber ich stelle mir nur allzu gerne die Sinnfrage
>> bei solchen Spezialitäten.

> Dagegen ist nichts einzuwenden, aber dazu solltest du erstmal die
> Hintergründe kennen. Erst danach kannst du fundiert sagen, ob es deiner
> Meinung nach sinnvoll ist oder nicht. Aber nur weil ein const an einer
> Stelle auftaucht, an der du es nicht erwartest, gleich mal drüber zu
> schimpfen, bringt nichts.

und Dr. Sommer (Gast) schrieb:

> PS: C++ hat noch eine Menge mehr schöne Dinge als nur versteckte
> this-Pointer und "const" zu bieten. Wenn du bei jedem so einen Aufstand
> machst ob man das wirklich braucht und ob das zu implizit ist, kommst du
> da nicht weit...

Ja, ich weiß, dass es da einiges zu beachten gibt. Ich hab deine 
Postings zu C++ hier immer mal wieder mitgelesen und wie Rolf Magnus 
schrieb sind da eben die "Hintergründe" der Sprache beachtenswert. Das 
const an dieser Stelle hatte halt gerade mein Verständnis etwas 
strapaziert. Ich war auch gerade nicht in der "akuten Lernphase C++", 
sondern sah das mit dem "const" hier im Code beiläufig. Sonst hätte ich 
gewiss nicht gemeckert, sondern mich erstmal selber schlau gelesen. Aber 
auch solche kleinen emotionalen Einwürfe führen manchmal wie gesagt 
beiläufig zu unerwarteten Erkenntnissen, vielleicht nicht nur für mich, 
sondern auch andere sind dadurch vielleicht gerade neugierig geworden.

Hab darum gestern nochmals den Gockel strapaziert und ein Beispiel 
gefunden

"Konstante Memberfunktionen"

http://msdn.microsoft.com/en-us/library/6ke686zh.aspx

Das Beispiel mal eben im VS2008 Express C++ als Win32 Konsolenanwendung 
compiliert. Prompt wirft der Compiler auch einen schönen Fehler an der 
Stelle, wo man versucht einer read-only Member function einen Wert 
zuzuweisen, nämlich
1
BirthDate.setMonth( 4 ); // C2662 Error
2
3
error C2662: 'Date::setMonth': this-Zeiger kann nicht von 'const Date' in 'Date &' konvertiert werden
4
1>        Durch die Konvertierung gehen Qualifizierer verloren
Auskommentiert lässt sich's dann erfolgreich compilieren, aber danach 
meldet sich der Linker und moniert (abgekürzt)
1
error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: __thiscall Date::Date(int,int,int)"
Wer jetzt anfängt nach diesem Linker error LNK2019 zu googeln, in der 
Hoffnung, daraus den Fehler zu erkennen wird nicht fündig werden. Für 
einen "error LNK2019" gibt es nämlich eine ganze Reihe unterschiedlicher 
Gründe und man sucht sich förmlich einen Ast. Böse Falle!

Da hat MS mal wieder ein Beispiel geliefert, dass einem den Spass an C++ 
schnell verderben kann, weil man als Neuling mit so einer Fehlermeldung 
nicht weiterkommt, sondern erst mal im Regen steht. Aber auch diese 
Hürde lässt sich nehmen, indem man wieder den Gockel lieber mit 
Stichworten aus dem Code bemüht und mit etwas Glück, sishe da

http://books.google.de/books?id=MeezQYeenDkC&pg=PA325&lpg=PA325&ots=bhHWOHbKmM&focus=viewport&dq=Date::Date%28int,int,int%29&hl=de

Na klar, hier
1
class Date
2
{
3
public:
4
   Date( int mn, int dy, int yr );
5
   int getMonth() const;     // A read-only function
6
   void setMonth( int mn );   // A write function; can't be const
7
private:
8
   int month;
9
};

"fehlt doch was". ;-)

Wo sind die Membervariablen, damit
1
Date MyDate( 7, 4, 1998 );

hier überhaupt funktioniert?
Wo also ist die Initialisierung im Konstruktor?
Hat MS wohl weggelassen, was ich bei Lernbeispielen nahezu "tödlich" 
finde, weil das schnell zu Frust führt und man nicht weiterkommt.

Also ran ans Werk, Bjarne Stroustrup's Beispiel folgend ergibt sich dann 
folgender Code
1
class Date
2
{
3
public:
4
   Date( int mn, int dy, int yr ) // Konstruktor mit INTERNER Zuweisung
5
   {
6
    m = mn;
7
    d = dy;
8
    y = yr;
9
   }
10
   
11
   int getMonth() const;     // A read-only function
12
   void setMonth( int mn );   // A write function; can't be const   
13
14
private:
15
   int m, d, y;
16
   int month;
17
};
18
19
int Date::getMonth() const
20
{
21
   return month;        // Doesn't modify anything
22
}
23
void Date::setMonth( int mn )
24
{
25
   month = mn;          // Modifies data member
26
}
27
28
int main()
29
{
30
   Date MyDate( 7, 4, 1998 );
31
   const Date BirthDate( 1, 18, 1953 );
32
   MyDate.setMonth( 4 );      // Okay
33
   BirthDate.getMonth();      // Okay
34
   //BirthDate.setMonth( 4 ); // C2662 Error
35
}

und voila, schon klappt's auch mit dem Linken. Im Debugger kann dann 
verfolgt werden was genau passiert.

Beim Lesen von Stroustrup wird man dann auch drauf gestoßen, wie der 
Memberinitialisierer auszuschauen hat, wenn das außerhalb der Klasse 
erfolgen soll. Dann kommt der Bereichsoperator "::" ins Spiel
1
Date::Date(int mn, int dy, int yr)  // Konstruktor
2
{
3
  m = mn;
4
  d = dy;
5
  y = yr;
6
}

oder in der verkürzten Form
1
// alternative Schreibweise
2
Date::Date(int mn, int dy, int yr)  // Konstruktor
3
  : m(mn), d(dy), y(yr)    // Memberinitialisierer
4
{
5
6
}

Also soweit mein Beispiel, welches zum Herumspielen einlädt. Nur aus 
trockenen Definitionen heraus würde ich persönlich die "C++ Denke" nicht 
verinnerlichen. Compilerfehler liefern aber meistens (leider nicht 
immer) nützliche Hinweise.

Beim mehr zufälligem (Quer-) Lesen von Stroustrub in diesem Artikel

http://www.heise.de/developer/artikel/Interview-mit-C-Schoepfer-Bjarne-Stroustrup-2300861.html

bin ich gestern dann auch noch auf Rust gestoßen. Das werde ich mir mal 
zu Gemüte führen. Der Aufreger übers const hat sich für mich also 
gelohnt.

;-)

von Mork vom Ork (Gast)


Lesenswert?

Achja, kleiner Hinweis noch, man darf natürlich gerne auch eine 
vollständige main() Funktion mit Rückgabewert und Parameter verwenden 
oder _tmain und vorkompilierte Header per #include "stdafx.h". Ebenso 
darf man typische C++ Header einbinden. Braucht es hier aber nicht, da 
hier nix zur Ausgabe verwendet wird. Nur der Vollständigkeit halber sei 
das erwähnt. Keep it as simple as possible bzw. KISS-Prinzip!

von Yalu X. (yalu) (Moderator)


Lesenswert?

Mork vom Ork schrieb:
> Wer jetzt anfängt nach diesem Linker error LNK2019 zu googeln, in der
> Hoffnung, daraus den Fehler zu erkennen wird nicht fündig werden. Für
> einen "error LNK2019" gibt es nämlich eine ganze Reihe unterschiedlicher
> Gründe und man sucht sich förmlich einen Ast. Böse Falle!

Das ist jetzt aber eine Fehlermeldung, wo einer, der schon mehr als ein
paar Tage C++ programmiert, wirklich nicht lange suchen muss. Da steht
ganz klar, dass
1
Date::Date(int,int,int)

nicht definiert ist. Hier fehlt also offensichtlich die Definition der
Memberfunktion Date der Klasse Date (also eines Konstruktors) mit
drei int-Argumenten.

Hättest du schon einmal eine richtig saftige, seitenlange Fehlermeldung
auf Grund einer inkorrekten Anwendungen eines Templates gesehen, würdest
du über die obige Meldung nur noch müde lächeln ;-)

Mork vom Ork schrieb:
> bin ich gestern dann auch noch auf Rust gestoßen. Das werde ich mir mal
> zu Gemüte führen.

Ja, Rust ist ein gutes Beispiel dafür, dass auch bei Programmiersprachen
mit C-ähnlicher Syntax noch deutliche Fortschritte zu dem Bestehenden
(C, C++, Java, C#, Objective-C usw.) möglich sind.

Das erste, was dir dort auffallen wird: Alle Variablen sind per Default
const, so wie es sinnvollerweise eigentlich auch in C++ sein sollte.
Soll eine Variable trotzdem überschrieben werden können, muss sie mit
mut deklariert werden.

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.