class Base
{
  friend void FnAmigaDeBase();
  private:
    void mPrivadoDeBase(){}
  protected:
    void mProtegidoDeBase(){}
  public:
    void mPublicoDeBase(){}
};

class Derivada : public Base
{  
  friend void FnAmigaDeDerivada();
  private:
    void mPrivadoDeDerivada(){}
  protected:
    void mProtegidoDeDerivada(){}
  public:
    void mPublicoDeDerivada(){}
};

void FnAmigaDeBase()
{
  Derivada objd;

  objd.mPrivadoDeBase();       // correcto
  objd.mProtegidoDeBase();     // correcto
  objd.mPublicoDeBase();       // correcto
  //objd.mPrivadoDeDerivada();   // error: no se puede acceder
     // a un miembro privado de la clase Derivada
  //objd.mProtegidoDeDerivada(); // error: no se puede acceder
     // a un miembro protegido de la clase Derivada
  objd.mPublicoDeDerivada();   // correcto
}

void FnAmigaDeDerivada()
{
  Derivada objd;

  //objd.mPrivadoDeBase();       // error: no se puede acceder
     // a un miembro privado de la clase Base
  objd.mProtegidoDeBase();     // correcto
  objd.mPublicoDeBase();       // correcto
  objd.mPrivadoDeDerivada();   // correcto
  objd.mProtegidoDeDerivada(); // correcto
  objd.mPublicoDeDerivada();   // correcto
}

int main()
{
  FnAmigaDeBase();
  FnAmigaDeDerivada();
}

