Señalando una variable a una función miembro en c ++
Es sorprendente descubrir que la mayoría de los programadores de C ++ no tienen idea de que un puntero llamado esta existe. Así esta es un gran secreto! Revel en ella! ¿Cuál es el secreto? El secreto es que usted puede tomar la dirección de la función miembro de un objeto para que pueda acceder directamente a los datos de la instancia de función miembro. Ooh-wee!
Ahora, recuerde que cada instancia de una clase obtiene su propia copia de las variables miembro, a menos que las variables son estáticas. Pero las funciones se comparten en toda la clase. Sí, se puede distinguir funciones estáticas de funciones no estáticos.
Pero eso solo se refiere a los tipos de variables que acceden: funciones estáticas pueden acceder a variables miembro estáticas solamente, y usted no necesita referirse a ellos con una instancia. No estático (es decir, normal y regular) Funciones miembro trabajan con un caso particular. Sin embargo, dentro de la memoria, existe realmente sólo una copia de la función.
Entonces, ¿cómo la función miembro sé a qué instancia de trabajar con? Un parámetro secreta se pasa a la función de miembro: el esta puntero. Suponga que tiene una clase llamada Gobstopper que tiene una función miembro llamada Mastique (). A continuación, usted tiene una instancia llamada MyGum, y se llama a la Mastique () la función de este modo:
MyGum.Chew () -
Cuando el compilador genera código ensamblador para esto, lo que realmente pasa un parámetro en la función - la dirección de la MyGum ejemplo, también conocido como el thispointer. Por lo tanto sólo una Mastique () función es en el código, pero llamarlo debe utilizar una instancia particular de la clase.
Debido a que sólo una copia de la Mastique () la función está en la memoria, usted puede tomar su dirección. Pero para ello se requiere algún tipo de código críptico buscando. Aquí está, rápido y al grano. Suponga que su clase tiene este aspecto:
clase Gobstopper {public: int WhichGobstopper-int Chew (string name) {cout lt; lt; WhichGobstopper lt; lt; endl-cout lt; lt; nombre lt; lt; endl retorno WhichGobstopper -}} -
los Mastique () función toma una cadena y devuelve un entero. Aquí está un typedef para un puntero a la Mastique () función:
typedef int (Gobstopper :: * GobMember) (cadena) -
Y aquí es una variable del tipo GobMember:
GobMember func = Gobstopper :: masticación
Si te fijas bien en la typedef, que se parece a un puntero a función regular. La única diferencia es que el nombre de clase y dos colones preceden al asterisco. Aparte de eso, es un puntero a función de edad regular.
Pero mientras que un puntero a función regular se limita a señalar que las funciones de un determinado conjunto de tipos de parámetros y un tipo de retorno, esta función acciones puntero esas restricciones, pero tiene una limitación adicional: Sólo se pueden señalar las funciones miembro de la clase Gobstopper.
Para llamar a la función almacenada en el puntero, es necesario tener un caso particular. Observe que en la asignación de func en el código anterior no había ningún caso, sólo el nombre de clase y función, Gobstopper :: Chew. Así que para llamar a la función, tomar un ejemplo, añadir func, ¡y ve!
los FunctionPointer02 ejemplo que se muestra contiene un ejemplo completo con la clase, la dirección de la función miembro, y dos casos separados.
#include#include utilizando Gobstopper espacio de nombres de clase std {public: int WhichGobstopper-int Chew (string name) {cout lt; lt; WhichGobstopper lt; lt; endl-cout lt; lt; nombre lt; lt; endl retorno WhichGobstopper -}} - int main () {typedef int (Gobstopper :: * GobMember) (cadena) -GobMember func = Gobstopper :: Chew-Gobstopper inst-inst.WhichGobstopper = 10 Gobstopper otra-another.WhichGobstopper = 20- (inst * func.) ("Greg W".) - (. Otra * func) ("Jennifer W.") -Retorno 0-}
Se puede ver en principal que primero se crea el tipo de la función, que se llama GobMember, y luego crear una variable, func, de ese tipo. Entonces se crea dos instancias de la Gobstopper clase y se les da a cada uno una diferente WhichGobstopper valor.
Por último, se llama a la función miembro, primero para la primera instancia y luego para la segunda instancia. Sólo para mostrar que usted puede tomar las direcciones de funciones con parámetros, se pasa en una cadena con algunos nombres.
Cuando se ejecuta el código, se puede ver desde la salida que es de hecho un llamamiento a la función miembro correcta para cada caso:
10Greg W.20Jennifer W.
Ahora, cuando usted dice " a la función miembro correcta para cada instancia, " lo que tu De Verdad significa es que el código está llamando a la misma función de miembro cada vez, pero utilizando una instancia diferente. Si usted está pensando en términos orientados a objetos, considere cada instancia como tener su propia copia de la función miembro. Por lo tanto, está bien que decir ". La función miembro correcta para cada instancia "