Recientemente utilicé punteros de función en el desarrollo, por lo que quería resolver el concepto de punteros de función. O (∩_∩) O ~
En primer lugar, el puntero de función es un puntero a un grupo de funciones del mismo tipo, y las funciones miembro de clase pueden considerarse de manera similar como punteros a funciones miembro del mismo tipo en la misma clase. Por supuesto, las funciones miembro aquí deberían ser más precisas Se refiere a funciones miembro no estáticas. El primero apunta directamente a la dirección de la función, mientras que en el segundo también podemos saber literalmente que debe estar relacionado con la clase y el objeto.
Ejemplo de puntero de función:
typedef int (* p) (int, int); // Defina un tipo de puntero de función que acepte dos tipos int y devuelva variables int int func (int x, int y) { printf ("func: x =% d, y =% d / n ", x, y); return (x <y? x: y); } int main () { p fun = func; // define un puntero de función y asígnele un puntero de función cout < <"min:" << (* fun) (4,5) << endl; // ¿Por qué * fun necesita expandirse con ()? Porque el operador de * tiene una prioridad menor que (), si no se usa () Se convierte en * (fun ()) return 0; } y el "puntero a la función miembro de la clase" tiene una diferencia de clase más: clase A { public: int func (int x, int y) { printf ("A :: func: x =% d, y =% d / n ", x, y); return (x <y? x: y); } }; typedef int (A :: * p) (int, int); / / El nombre del puntero debe agregarse antes del tipo de nombre de clase A :: calificado int main () { p fun = & A :: func; A a; // Debido a que la desreferenciación de la dirección de la función miembro debe estar asociada a la dirección de un objeto, debemos crear un objeto. cout << "min:" << (a. * diversión) (4,5) << endl; return 0; }
Hola . Solo úsalo. * Se siente raro.
A continuación, podemos expandir lo siguiente:
#include <tchar.h> #include <iostream> #include <stdio.h> usando el espacio de nombres std; clase A { public: int func1 (int x, int y) { printf ("A :: func: x =% d, y =% d / n", x, y); retorno (x <y? x: y); } virtual int func2 (int x, int y) { printf ("A :: func: x =% d, y =% d / n", x, y); retorno (x> y? x: y); } }; clase B: público A { público: virtual int func2 (int x, int y) { printf ("B :: func: x =% d, y =% d / n", x, y); retorno (x + y); } }; typedef int (A :: * p) (int, int); // 指针 名 前 一定 要 加上 所属 类型 类 名 A :: 的 限定 typedef int (B :: * p0) (int, int); int main () { A a; // Debido a que la desreferenciación de la dirección de la función miembro debe estar asociada a la dirección de un objeto, debemos crear un objeto. B b; p fun = & A :: func1; cout << (a. * Fun) (4,5) << endl; cout << (b. * Fun) (4,5) << endl << endl; fun = & A :: func2; cout << (a. * fun) (4,5) << endl; // Tenga en cuenta que la función llamada aquí es una función virtual, y el puntero a la función miembro de la clase de magia realmente admite polimorfismo. cout << (b. * fun) (4,5) << endl << endl; // fun = & B :: func2; // Este tipo de error cae, porque no hay un "puntero a la función miembro de clase de la clase derivada" La conversión implícita de "puntero a función miembro de clase" a clase base fun = (int (A :: *) (int, int)) & B :: func2; // cout << (a. * diversión) (4,5) << endl; cout << (b. * diversión) (4,5) << endl << endl; p0 fun0 = & B :: func2; cout << (a. * diversión) (4,5) << endl; cout << (b. * Diversión) (4,5) << endl << endl cout << (a. * diversión) (4,5) << endl; cout << (b. * diversión) (4,5) << endl << endl;
// De lo anterior se puede encontrar fácilmente el puntero relación exactamente opuesta a la clase base y las relaciones de clase derivadas y clases de objetos puntero que apunta a la clase base y la clase derivada de una función miembro de la clase,
el diseño // función miembro de la clase base se considera que es una clase derivada Un subconjunto del diseño de la función miembro
devuelve 0;
}
El siguiente es el uso de punteros para las funciones de miembro de clase de la clase de plantilla
Los ejemplos son los siguientes:
#include <tchar.h> #include <iostream> #include <stdio.h> usando el espacio de nombres std; clase A { public : int func ( int x, int y) { printf ( " A :: func: x =% d, y =% d / n " , x, y); retorno (x <y? x: y); } }; clase B { public : int func ( int x, int y) { printf ( " B :: func: x =% d, y =% d / n ", x, y); retorno (x> y? x: y); } }; plantilla < clase T> clase C { public : T c; vacío Print () { int (T :: * p) ( int , int ) = & T :: func; (c. * p) ( 4 , 5 ); } }; int main () { C <A> ca; C <B> cb; ca.Print (); cb.Print (); devuelve 0 ; }
Se puede ver claramente desde arriba. . De hecho, no es diferente de las plantillas ordinarias. . Es solo que el nombre calificado debe estar bien. . .
Hola . .