2010-05-10 16 views
13

¿Cuál es el propósito de los siguientes operadores esotéricos de C++?operadores esotéricos de C++

Puntero a miembro

::* 

Enlazar puntero a miembro por puntero

->* 

puntero de enlace al miembro por referencia

.* 

(reference)

+9

Independientemente de lo que dice wikipedia, ':: *' no es un operador. –

Respuesta

24

Un puntero a un miembro le permite tener un puntero relativo a una clase específica.

Entonces, supongamos que tiene una clase de contacto con varios números de teléfono.

class contact 
{ 
    phonenumber office; 
    phonenumber home; 
    phonenumber cell; 
}; 

La idea es que si usted tiene un algoritmo que tiene que utilizar un número de teléfono, pero la decisión de qué número de teléfono debe hacerse fuera del algoritmo, punteros a miembro de resolver el problema:

void robocall(phonenumber contact::*number, ...); 

ahora la persona que llama de robocall puede decidir qué tipo de numero de teléfono de empleo:

robocall(&contact::home, ...); // call home numbers 
robocall(&contact::office, ...); // call office number 

.* y ->* entrar en juego una vez que tenga un puntero. Así que dentro de robocall, que haría:

contact c = ...; 
c.*number; // gets the appropriate phone number of the object 

o:

contact *pc = ...; 
pc->*number; 
+0

Eso es realmente genial. –

+0

Hay una guía legible en InformIT en [Punteros a miembros] (http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=142). –

+0

Este es un buen ejemplo de esto: http://msdn.microsoft.com/en-us/library/k8336763.aspx –

2

Mira la C++ FAQ Lite's section on pointers to member functions. Busque los "operadores" específicos de los que está hablando (en la mayoría de los navegadores, Ctrl-F abre un cuadro de diálogo Buscar/buscar que le permite buscar texto en la página web) y le ayudará a comprender mejor las cosas.

0

Respuesta simplificada: estos operadores permiten llamar a funciones miembro como funciones 'regulares' (al menos se ve igual desde la perspectiva del usuario final). Ejemplo del mundo real: se usan mucho en varias implementaciones de devolución de llamada.

4

No existe un operador como ::* y nunca ha existido. No sé de dónde lo sacaste.

En cuanto a ->* y .* - estos son los operadores dereference para punteros de -puntero a miembro tipo.

struct S { 
    int i; 
}; 

int main() { 
    int S::*pi = &S::i; // pointer of pointer-to-member type 

    S s; 
    S* ps = &s; 

    s.*pi = 0; // operator `.*` used 
    assert(s.i == 0); 

    ps->*pi = 1; // operator `->*` used 
    assert(s.i == 1); 
} 

En cuanto a lo punteros-a-miembros son ... lo que hace su libro favorito C++ decir sobre el tema?

+0

Obtuve :: * de wikipedia enumerado como la referencia a mi pregunta. –

+0

:: * compila muy bien en g ++. –

+0

@Neil G: ¿Qué exactamente "compila bien en g ++"? – AnT

0

Estos le permiten tener punteros a las funciones de miembro (y variables de miembro) que están vinculadas a una instancia particular de la clase.

Los punteros a las funciones de miembro pueden ser útiles para cosas como implementaciones livianas del patrón de estado.En general, cada vez que desee variar el comportamiento de un objeto a lo largo del tiempo sin recurrir a cambiar el objeto completo, puede considerar el uso de punteros para las funciones de los miembros.

Los indicadores de las variables miembro se pueden usar si desea, por ejemplo, implementar un algoritmo genérico para buscar una matriz de estructuras para una entrada que tiene un valor particular para un campo dado.

3

Se relacionan con punteros a miembros y funciones de punteros a miembros.

struct Foo { 
    int a() { return 1; } 
    int b() { return 2; } 
    int c; 
}; 

int main() { 
    Foo f; 
    f.c = 3; 

    typedef int (Foo::*member_fn)(); // pointer-to-member-function 
    typedef int (Foo::*data_member); // pointer-to-member 

    member_fn mf = &Foo::a; 
    (f.*mf)(); // calls the member function pointed to by mf. returns 1 
    mf = &Foo::b; 
    (f.*mf)(); // This time, returns 2, since mf points to b 
    Foo *fp = &f; 
    (fp->*mf)(); // same thing, via pointer to f instead of object/reference f. 

    data_member dm = &Foo::c; 
    f.*dm; // is 3 
    f.*dm = 5; 
    f.c; // is now 5. 

    Foo f2; // another instance 
    f2.c = 12; 
    f2.*dm; // is 12. Same pointer-to-member, different object. 
} 

Aunque pueda parecer una, ::* no es un operador. Es el operador :: y el * operador modificador de tipo uno al lado del otro. Para probar esto sin recurrir a leer el estándar, intente agregar espacios: :: * compila, . * no lo hace, ni tampoco -> *.

En cuanto a lo que realmente son útiles, el mismo principio que los punteros a las funciones. No los usaría como lo hice anteriormente, en una situación en la que podría simplemente llamar a la función por su nombre, pero puede pasarlos como parámetros o devolverlos desde funciones, almacenarlos o seleccionar uno de varios basados ​​en lógica complicada.

Si ayuda, creo que la sintaxis se elige de manera que aunque .* es un solo operador indivisibles, se puede imaginar que *dm "significa" c, el miembro apuntado por dm. Por lo tanto, si dm apunta a c, entonces f.*dm es lo mismo que f.c.