» » Curso De C++ - Parte 74

Curso De C++ - Parte 74

Curso De C++ - Parte 74
 

Curso De C++ - Parte 74

Punteros a miembros de clases o estructuras

C++ permite declarar punteros a miembros de clases, estructuras y uniones. Aunque en el caso de las clases, los miembros deben ser públicos para que pueda accederse a ellos.

La sintaxis para la declaración de un puntero a un miembro es la siguiente:
<tipo> <clase|estructura|unión>::*<identificador>;
De este modo se declara un puntero "identificador" a un miembro de tipo "tipo" de la clase, estructura o unión especificada.
Ejemplos:
struct punto3D {
   int x;
   int y;
   int z;
};

class registro {
  public:
   registro();
   
   float v;
   float w;
};

int punto3D::*coordenada; // (1)
float registro::*valor;   // (2) 
El primer ejemplo declara un puntero "coordenada" a un miembro de tipo int de la estructura "punto3D". El segundo declara un puntero "valor" a un miembro público de la clase "registro".
 
Asignación de valores a punteros a miembro

Una vez declarado un puntero, debemos asignarle la dirección de un miembro del tipo adecuado de la clase, estructura o unión. Podremos asignarle la dirección de cualquiera de los miembros del tipo adecuado. La sintaxis es:
<identificador> = &<clase|estructura|unión>::<campo>;
En el ejemplo anterior, serían válidas las siguientes asignaciones:
coordenada = &punto3D::x; 
coordenada = &punto3D::y;
coordenada = &punto3D::z;
valor = &registro::v;
valor = &registro::w;

Operadores .* y ->*
 
Ahora bien, ya sabemos cómo declarar punteros a miembros, pero no cómo trabajar con ellos.
C++ dispone de dos operadores para trabajar con punteros a miembros: .* y ->*. A lo mejor los echabas de menos :-).

Se trata de dos variantes del mismo operador, uno para objetos y otro para punteros:
<objeto>.*<puntero>
<puntero_a_objeto>->*<puntero>
La primera forma se usa cuando tratamos de acceder a un miembro de un objeto.
La segunda cuando lo hacemos a través de un puntero a un objeto.
Veamos un ejemplo completo:
#include <iostream>
using namespace std;

class clase {
  public:
   clase(int a, int b) : x(a), y(b) {}
   
  public:
   int x;
   int y;
};

int main() {
   clase uno(6,10);
   clase *dos = new clase(88,99);
   int clase::*puntero;
     
   puntero = &clase::x;
   cout << uno.*puntero << endl;
   cout << dos->*puntero << endl;

   puntero = &amp;clase::y;
   cout << uno.*puntero << endl;
   cout << dos->*puntero << endl;
   
   delete dos;
   return 0;
} 
La utilidad práctica no es probable que se presente frecuentemente, y casi nunca con clases, ya que no es corriente declarar miembros públicos. Sin embargo nos ofrece algunas posibilidades interesantes a la hora de recorrer miembros concretos de arrays de estructuras, aplicando la misma función o expresión a cada uno.

También debemos recordar que es posible declarar punteros a funciones, y las funciones miembros de clases no son una excepción. En ese caso sí es corriente que existan funciones públicas.

#include <iostream>
using namespace std;

class clase {
  public:
   clase(int a, int b) : x(a), y(b) {}
   int funcion(int a) { 
      if(0 == a) return x; else return y; 
   }
   
  private:
   int x;
   int y;
};

int main() {
   clase uno(6,10);
   clase *dos = new clase(88,99);
   int (clase::*pfun)(int);
   
   pfun = &clase::funcion;
   
   cout << (uno.*pfun)(0) << endl;
   cout << (uno.*pfun)(1) << endl;
   cout << (dos->*pfun)(0) << endl;
   cout << (dos->*pfun)(1) << endl;
 
   delete dos;
   return 0;
} 
Para ejecutar una función desde un puntero a miembro hay que usar los paréntesis, ya que el operador de llamada a función "()" tiene mayor prioridad que los operadores ".*" y "->*".
Leccion Parte 75

Deja un comentario

Información
Atención! Usuarios que están en este grupo no pueden dejar comentarios en la página...Primero debes Registrarse!