[Mi respuesta original no tenía sentido. Disculpas por eso. Gracias a @celtschk por señalarlo y proporcionar la mejor respuesta.]
Si C
es un amigo de B
, se puede acceder a todos los miembros B
's, ya sea privada, pública o protegida, y que incluye la accesibles miembros (públicos y protegidos) que forman parte de un subobjeto de base:
struct A { protected: int a; };
struct B : A { private: int b; friend struct C; }
struct C
{
B x;
A w;
void f()
{
x.a = 1; // fine
x.b = 2; // fine
// w.a = 0; /* Error, #1 */
}
friend struct D; // see below
};
sin embargo, la amistad no es ni transitiva ni heredada: C
es un amigo de B
, pero no de A
(ver # 1). Además, si D
es un amigo de C
, entonces D
no hay nada del acceso que C
's amistad a B
permite que, por lo D
no pueden acceder a B
' s miembros no públicos. Del mismo modo, si struct E : C
hereda de C
, entonces E
tampoco es amigo de B
automáticamente:
struct D
{
B y;
void g()
{
// y.b = 3; /* Error! */
}
};
struct E : C
{
B z;
void h()
{
// y.b = 4; /* Error! */
}
}
Tal vez se puede resumir lo que está pasando en algunos puntos:
Una clase derivada tiene acceso a todos los miembros públicos y protegidos de cada clase base.
Un amigo de una clase tiene acceso a todos los miembros de esa clase a los que tiene acceso (es decir, todos los miembros que excluyen miembros de base privados).
La amistad no se hereda: si una clase tiene un amigo, esa amistad no se aplica a ninguna de sus clases base ni a ninguna de sus clases derivadas.
Un amigo de un amigo no es un amigo.
Esta es la mejor respuesta para la pregunta original. –
@KerrekSB: Gracias. – celtschk