2012-03-26 20 views
5

Biorąc przykładowy kod:Czy znajomy widzi klasy bazowe?

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; 
    } 
}; 

Czy bycie przyjacielem dać mi wszystko chciałbym uzyskać dostęp jakbym był członkiem funkcji w klasie, do której jestem przyjaciela? Innymi słowy, czy mogę dostać się do chronionych i publicznych członków klasy bazowej, która jest prywatnie dziedziczona, odkąd jestem przyjacielem?

+5

skoro już poszedł sobie trud, aby napisać przykładowy kod, próbowałeś go * * kompilacji? Ten rodzaj odpowiedzi szybko wyjdzie na jaw w ostrzeżeniach/brakach. – ssube

+2

@peachykeen: Jakie kompilatory akceptują i co standard mówi, to często różne rzeczy. Ponadto, teoretycznie mogą istnieć subtelności, których nie obejmuje próbny kod. –

+0

@AdrianMcCarthy To prawda. Jednak wiele kompilatorów będzie ostrzegać, gdy będą używane niestandardowe funkcje, a jeśli będzie to niezgodne ze standardem i implementacją kompilatora, otrzymasz krótką i słodką odpowiedź. Chociaż nie jest to niezawodne, nie może zaszkodzić spróbować. – ssube

Odpowiedz

6

Łącząc odpowiedź David Rodríguez - dribeas i Luchian GRIGORE:

Tak, przykład w pytaniu działa, jednak, jak David wskazuje chronionego członkowie nie są dostępne bezpośrednio z klasy bazowej. Dostęp do chronionych członków uzyskujesz tylko po uzyskaniu dostępu przez Derived, nie masz dostępu do tych samych członków po uzyskaniu dostępu przez Base.

Innymi słowy, chronieni członkowie bazy są traktowani tak, jakby byli członkami prywatnymi wywodzącymi się z nich, dzięki czemu przyjaciele mogą je zobaczyć, ale jeśli rzucisz klasę podstawową, nie ma związku z przyjacielem, a tym samym chronionym członkowie nie są już dostępni.

Oto przykład, który wyjaśnia różnicę:

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

Deklaracja przyjaciela sprawi, że MyFriend będzie miał dostęp do relacji dziedziczenia (czyli private dla reszty świata), ale nie zapewni jej dostępu do chronionych członków bazy, tylko do publicznego interfejsu.

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

Tak, ponieważ Base 's członkowie są również Derived' s członków (ponieważ nie są one private w Base).

Powiązane problemy