2010-05-06 23 views
7

He leído sobre los punteros a los miembros de la clase, pero nunca los he visto en ninguna aplicación práctica. ¿Alguien puede explicar cuáles son los casos de uso de tales punteros? ¿Es realmente necesario tener tales punteros?¿Para qué sirven los indicadores para los miembros de la clase?

Por ejemplo.

class abc 
{ 
public: 
    int a; 
    abc(int val) { a = val; } 
}; 

int main() 
{ 
    int abc::*data; 
    abc obj(5); 

    data = &abc::a; 

    cout << "Value of a is " << obj.*data << endl; 

    return 0; 
} 

En el ejemplo anterior. ¿Por qué se accede al valor de 'a' de esta manera? ¿Cuál es la ventaja de usar punteros a los miembros de la clase?

Respuesta

9

La mayor ventaja de un puntero a miembro o puntero a miembro de funciones es que

  • no tiene que unirse a una instancia específica de inmediato
  • no necesitan para colocar restricciones en los nombres de los miembros, solo el tipo tiene que coincidir.

Esto se puede utilizar, p. devoluciones de llamadas o algoritmos abstractos:

std::map<int,int> m; 
m.insert(std::make_pair(1,2)); 
m.insert(std::make_pair(3,4)); 
m.insert(std::make_pair(5,6)); 
std::ptrdiff_t s = 
    std::count_if(m.begin(), m.end(), 
        boost::bind(&std::map<int,int>::value_type::first, _1) > 2); 
std::cout << s << std::endl; // 2 

Tenga en cuenta que Boost.Bind, Boost.Function y sus equivalentes TR1 ya que encapsulan muy bien para usted. Hasta cierto punto, el estándar actual también incluye herramientas como std::mem_fun en <functional>.

+0

'std :: mem_fun()' et al. confíe en puntero-a-miembro. – wilhelmtell

+0

Sí, pero encapsulan el uso; raramente he necesitado declarar punteros a miembro desde hace bastante tiempo. –

+0

Para la claridad de la demostración, probablemente habría usado el 'map :: operator []': la combinación 'insert' y' make_pair' es tan prolija: p Buena respuesta gracias :) –

2

Si ha utilizado MFC, verá punteros a concepto de función miembro es muy usada (internamente)

DECLARE_MESSAGE_MAP, BEGIN_MESSAGE_MAP, END_MESSAGE_MAP Ver Message Maps

0

La pregunta que yo supongo es: "¿Qué puntero a los datos de los miembros agregar más puntero simple a los datos? " y la única respuesta que puedo pensar es un nivel de significado explícito: estamos apuntando a los datos en esta clase.

Ahora puedo ver algo de valor en lo que es efectivamente alguna documentación adicional de intención. Un ejemplo que he visto que podría ser bastante poderoso es cuando nuestra "clase" es en realidad una estructura C heredada. Ahora no tenemos métodos locales de esa estructura, por lo que tener algunos punteros que están explícitamente asociados con esa estructura puede hacer que nuestro código sea más claro.

+1

Si especifica tanto la instancia de clase como la variable, tiene un puntero normal (la dirección está completamente especificada). Es cuando especificas la variable, pero no la instancia de la clase, que obtienes un puntero a miembro, que es prácticamente el desplazamiento desde el inicio de la instancia hasta donde se almacena esa variable. Es suficiente información para iniciar y acceder a la variable en cualquier instancia de la clase. –

0

puntero a miembro-es, al igual que todos los C++ características, simplemente azúcar sintáctica para algo que ya podría haber hecho en pura C.

punteros a miembro variables son bastante simples. Un caso de uso es si desea escribir una función (plantilla) que pueda ordenar una matriz de estructuras por cualquier campo. Al pasar un puntero a miembro, puede recuperar algún campo específico de cualquier instancia de la estructura sin tener que codificar el campo. Por supuesto, un functor que acepta un puntero de estructura y devuelve el valor del campo podría haberse utilizado en su lugar.

Los punteros a la función de miembro son un poco más complicados. A primera vista, son como los indicadores de función comunes que saben cómo pasar el puntero "este" oculto. Pero las funciones virtuales hacen que una idea simple sea bastante complicada.

Y las clases base virtuales hacen que todos los punteros sean muy complicados. No es algo que quieras codificar tú mismo usando constructos C simples. Pero los casos complejos son raros.

Cuestiones relacionadas