Punteros a de clases o estructuras
C++ permite declarar punteros a de clases, estructuras y uniones. Aunque en el caso de las clases, los 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 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 = ®istro::v;
valor = ®istro::w;
|
Operadores .* y ->*
Ahora bien, ya sabemos cómo declarar punteros a , pero no cómo trabajar con ellos.
C++ dispone de dos operadores para trabajar con punteros a : .* 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 = &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 públicos. Sin embargo nos ofrece algunas posibilidades interesantes a la hora de recorrer 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 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 "->*".
Ir al Principio
Comentarios