static und ableitung
-
Hallo zusammen,
ich habe folgenden Sachverhalt.
class User; class Base { protected: static void Foo(){} }; class Inherit : public Base { friend User; }; class User { public: void Bar() { Base::Foo(); // ? Warum funktioniert das hier. Inherit::Foo(); } }; int main() { User t; t.Bar(); }Kann mir einer von euch sagen warum das funktioniert. Ist das im Standard irgendwo beschrieben wie die statischen Funktionen bei Ableitung gehandhabt werden?
Danke für die Hilfe.
Grüße
Tobi
-
User ist ein friend von Inherit. friend heißt, dass User nach Belieben in den Eingeweiden von Inherit herumwurschteln darf, das heißt es hat auf alles Zugriff, worauf Inherit Zugriff hat (mit Ausnahme der Eingeweide von Klassen, die Inherit als friend deklariert haben).
Es hat insbesondere auch Zugriff auf die Teile von Foo, die Foo protected deklariert hat, weil die an Inherit vererbt werden.
Merke: friend ist die engste und übelste Bindung, die du überhaupt nur haben kannst, noch enger als Vererbung. Ich benutze friend aus dem Grund so gut wie nie (kann mich an kein Beispiel erinnern wo ich es benutzen würde).C++ - where friends can touch your privates, but your family can't.
-
Was ist daran so verwunderlich Inherit ist ein Base!?
-
dot schrieb:
Was ist daran so verwunderlich Inherit ist ein Base!?
Die Frage ist doch, warum man ein Base::Foo aufrufen kann. Lässt man das static weg, gehts wie erwartet nicht:
class User; class Base { protected: void Foo(){} }; class Inherit : public Base { friend class User; }; class User { public: void Bar() { Base *b; Inherit *i; i = new Inherit(); b = i; b->Foo(); // ? Warum funktioniert das hier. i->Foo(); } }; int main() { User t; t.Bar(); }Führt erwartungsgemäß zum Fehler:
base.cpp: In member function 'void User::Bar()':
base.cpp:6: error: 'void Base::Foo()' is protected
base.cpp:23: error: within this context
-

pumuckl schrieb:
User ist ein friend von Inherit. friend heißt, dass User nach Belieben in den Eingeweiden von Inherit herumwurschteln darf, das heißt es hat auf alles Zugriff, worauf Inherit Zugriff hat (mit Ausnahme der Eingeweide von Klassen, die Inherit als friend deklariert haben).
Es hat insbesondere auch Zugriff auf die Teile von Foo, die Foo protected deklariert hat, weil die an Inherit vererbt werden.
Merke: friend ist die engste und übelste Bindung, die du überhaupt nur haben kannst, noch enger als Vererbung. Ich benutze friend aus dem Grund so gut wie nie (kann mich an kein Beispiel erinnern wo ich es benutzen würde).C++ - where friends can touch your privates, but your family can't.
Hallo Pumuckl,
danke für die Info, jetzt wird es mir klar... Der friend wurde bei uns im Review auch gefunden und wir haben uns gewundert warum es funktioniert. Wir haben einfach zu kompliziert gedacht.
Danke

-
pumuckl schrieb:
User ist ein friend von Inherit. friend heißt, dass User nach Belieben in den Eingeweiden von Inherit herumwurschteln darf, das heißt es hat auf alles Zugriff, worauf Inherit Zugriff hat
Seit wann ist
friendtransitiv?Userist ein Freund vonInherit, nicht vonBase. DassUserdadurch direkt Zugriff aufBasehat, finde ich unlogisch. Lässt man nämlich dieInherit-Klasse weg, gehts nicht. Wie von manni66 hervorgehoben, gilt das Gleiche für nicht-statische Methoden.Steht das überhaupt so im Standard? Übrigens interessant, dass Comeau und MSVC
friendstattfriend classkompilieren...pumuckl schrieb:
Ich benutze friend aus dem Grund so gut wie nie (kann mich an kein Beispiel erinnern wo ich es benutzen würde).
Strikte Kapselung ist in der Theorie ja schön, aber manchmal ist
friendunausweichlich, wenn man seine öffentliche Schnittstelle sauber halten will. Sauber heisst, keine Funktionalität duplizieren oder nur aus technischen Gründen (andere Klassen benötigen Zugriff auf sie) anbieten.
-
- friend ist nicht transitiv.
- friend class X ist gleichzeitig eine Vorwärtsdeklaration. Wenn schon irgendwo weiter oben class X; steht ist friend X; auch gültig.
- ...wieso das proteced static komisch spielt, ist mir auch schleierhaft

-
KasF schrieb:
friend class X ist gleichzeitig eine Vorwärtsdeklaration.
Das ist im Prinzip richtig, aber ohne Relevanz. Eine friend-Deklaration injiziert nämlich den entsprechenden Nahmen nicht in den umliegenden Namensraum, dieser Name wird also weder durch qualifiziertes noch durch unqualifiziertes Lookup gefunden werden.