2012-03-26 18 views
5

den Beispielcode Gegeben:Sieht ein Freund Basisklassen?

class Base { 
public: 
    bool pub; 
protected: 
    bool prot; 
}; 

class Derived : private Base { 
    friend class MyFriend; 
}; 

class MyFriend { 
    Derived _derived; 

    void test() { 
    // Does standard provide me access to _derived.pub and _derived.prot? 
    cout << "Am I allowed access to this: " << _derived.pub 
     << " and this: " << _derived.prot; 
    } 
}; 

ein Freund alle Zugang geben Sie mir bedeutet es ich bekommen würde, als ob ich eine Member-Funktion innerhalb der Klasse war, an dem ich einen Freund? Mit anderen Worten, kann ich an die geschützten und öffentlichen Mitglieder der Basisklasse gelangen, die von mir privat geerbt wird, seit ich ein Freund bin?

+5

Sehen, wie Sie sich die Mühe gemacht haben Beispiel-Code zu schreiben, haben Sie versucht, * es kompilieren *? Diese Art von Antwort würde sehr schnell in den Warnungen/Mangel an Licht kommen. – ssube

+2

@peachykeen: Was Compiler akzeptieren und was der Standard sagt sind oft verschiedene Dinge. Außerdem könnte es theoretisch Feinheiten geben, die der Beispielcode nicht erfasst. –

+0

@AdrianMcCarthy Das ist wahr. Viele Compiler warnen jedoch, wenn nicht standardmäßige Funktionen verwendet werden, und wenn es gegen den Standard und die Implementierung des Compilers verstößt, erhalten Sie eine kurze und süße Antwort. Obwohl es nicht narrensicher ist, kann es nicht schaden, es zu versuchen. – ssube

Antwort

6

die Antworten von David Rodríguez Kombination - dribeas und Luchian Grigore:

Ja, das Beispiel in der Frage arbeitet, aber, wie David weist darauf hin, die geschützten Mitglieder nicht direkt durch die Basisklasse zugänglich. Sie erhalten nur Zugriff auf die geschützten Mitglieder, wenn Sie über Derived darauf zugreifen. Wenn Sie über Base darauf zugreifen, haben Sie keinen Zugriff auf dieselben Mitglieder. Mit anderen Worten, die geschützten Mitglieder der Basis werden behandelt, als wären sie private Mitglieder von abgeleiteten und somit können Freunde sie sehen, aber wenn Sie in die Basisklasse umwandeln, gibt es keine Freundschaftsbeziehung und somit auch die geschützte Mitglieder sind nicht mehr erreichbar. Hier

ist ein Beispiel, das den Unterschied verdeutlicht:

class MyFriend { 
    Derived _derived; 

    void test() { 
    bool thisWorks = _derived.pub; 
    bool thisAlsoWorks = _derived.prot; 

    Base &castToBase = _derived; 

    bool onlyPublicAccessNow = castToBase.pub; 
    // Compiler error on next expression only. 
    // test.cpp:13: error: `bool Base::prot' is protected 
    bool noAccessToProtected = castToBase.prot; 
    } 
}; 
2

Die Friend-Deklaration wird MyFriend haben Zugriff auf die Vererbungsbeziehung (das ist private für den Rest der Welt), aber gewährt es nicht Zugriff auf die geschützten Mitglieder der Basis, nur für die öffentliche Schnittstelle.

void MyFriend::test() { 
    Derived d; 
    Base & b = d;   // Allowed, MyFriend has access to the relationship 
    b.prot = false;  // Not allowed, it does not have access to the base 
} 
1

Ja, weil Base s Mitglieder s Mitglieder auch Derived sind "(da sie nicht private in Base sind).