// punteros.cpp - Punteros a miembros de una clase
#include <iostream>
#include <iomanip>
using namespace std;

/////////////////////////////////////////////////////////////////
// Definición de la clase CNotas
class CNotas
{
  private:
    float nota;
  public:
    CNotas(float n = 0): nota(n) {};
    void AsignarNota(float n);
    float ObtenerNota() const;
};

void CNotas::AsignarNota(float n) { nota = n; }

float CNotas::ObtenerNota() const
{
  //return nota;

  // Definir un puntero al dato miembro nota
  float CNotas::*pdmNota = &CNotas::nota;

  //return (*this).*pdmNota;
  return this->*pdmNota;
}
/////////////////////////////////////////////////////////////////

// Prototipos de funciones
void Visualizar(CNotas *);

// Definir el tipo derivado pfnm: puntero a un método
typedef void (CNotas::*pfnm)(float);

int main()
{
  CNotas alumno;
  CNotas *palumno = new CNotas;
  float nota;

  // Definir los tipos derivados pfnmAsignarNota:
  // puntero al método AsignarNota
  pfnm pfnmAsignarNota = &CNotas::AsignarNota;

  // Introducir datos
  cout << "Nota del alumno: ";
  cin >> nota;
  //alumno.AsignarNota( nota );
  (alumno.*pfnmAsignarNota)(nota);

  cout << "Nota del alumno: ";
  cin >> nota;
  //palumno->AsignarNota( nota );
  (palumno->*pfnmAsignarNota)(nota);
  // Visualizar el contenido de los objetos
  cout << endl;
  cout << "alumno 1, nota: ";
  Visualizar(&alumno);
  cout << "alumno 2, nota: ";
  Visualizar(palumno);

  delete palumno;
}

void Visualizar(CNotas *palumno)
{
  cout << fixed << setprecision(2);
  cout << setw(12) << palumno->ObtenerNota() << endl;
}

