2012-03-26 18 views
5

Teniendo en cuenta el código de ejemplo:¿Un amigo ve las clases base?

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

¿Ser un amigo me dan todos los accesos que obtendría como si fuera una función miembro de la clase a la que soy un amigo? En otras palabras, ¿puedo acceder a los miembros protegidos y públicos de la clase base que se hereda de forma privada desde que soy un amigo?

+5

En vista de que usted ha tomado la molestia de escribir código de ejemplo, has * * compilación? Este tipo de respuesta saldría a la luz rápidamente en las advertencias/falta de. – ssube

+2

@peachykeen: lo que los compiladores aceptan y lo que dice el estándar son a menudo cosas diferentes. Además, podría haber, en teoría, sutilezas que el código de muestra no captura. –

+0

@AdrianMcCarthy Eso es verdad. Sin embargo, muchos compiladores advertirán cuando se utilicen características no estándar, y si va en contra del estándar y la implementación del compilador, obtendrá una respuesta breve y dulce. Si bien no es infalible, no puede doler intentarlo. – ssube

Respuesta

6

La combinación de las respuestas de David Rodríguez - dribeas y Luchian Grigore:

Sí, el ejemplo de la cuestión funciona, sin embargo, como señala David, los miembros protegidos no son accesibles directamente a través de la clase base. Solo tiene acceso a los miembros protegidos cuando se accede a través del Derived, no tiene acceso a los mismos miembros cuando se accede a través del Base.

En otras palabras, los miembros protegidos de la base se tratan como si fueran miembros privados de derivados y así los amigos pueden verlos, pero, si se lanza a la clase base, no hay relación de amistad, y por lo tanto la protección los miembros ya no son accesibles.

Aquí es un ejemplo que aclara la diferencia:

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

La declaración de amigo hará que MyFriend tenga acceso a la relación de herencia (es decir, private para el resto del mundo) pero no le otorgará acceso a los miembros protegidos de la base, solo a la interfaz pública.

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

Sí, porque Base 's miembros son también Derived' s miembros (ya que no son private en Base).