2012-09-06 13 views
5

Estoy tratando de hacer algo con punteros para los miembros de la función que no puedo 'averiguar cómo funciona esto.puntero al miembro de la función

tengo una clase A que se ve algo como esto

class A 
{ 
    public: 
    float Plus (float a, float b) { return a+b; } 
    float Minus (float a, float b) { return a-b; } 
    float Multiply(float a, float b) { return a*b; } 
    float Divide (float a, float b) { return a/b; } 
}; 

Quiero declarar un puntero a una y luego pasar a otra función de un puntero de función a uno de los miembros de A.

algo le gusta esto:

void Will_Get_Function_Pointer(float a, float b, float (A::*pt2Func)(float, float)) 
{ 
    (...) 
} 

Donde yo lo llamaría con algo como esto

A* myA = new A; 
Will_Get_Function_Pointer(1.00,2.00, &myA->Minus) 

no puedo utilizar miembros estáticos/const porque en mi aplicación definitiva Una apuntará a una Un específico en una colección de objetos A en algo que va a tener este aspecto

vector<A> vecA; 
myA = &vecA[xxx] 

Hacer esto falla miserablemente

typedef float (A::*pA)(float x, float y); 
pA p = &myA->Minus; 

y el compilador me dice que use & A :: Minus, pero que no funcionará para mí.

¿Puedo hacer esto?

Saludos

Respuesta

6
A* myA = new A; 
Will_Get_Function_Pointer(1.00,2.00, &myA->Minus) 

no se puede. Usted debe usar algo como

void Will_Get_Function_Pointer(A* object, float a, float b, 
float (A::*pt2Func)(float, float)) 
{ 
    (object->*pt2Func)(a, b); 
} 

y lo llama como

A* myA = new A; 
Will_Get_Function_Pointer(myA, 1.00, 2.00, &A::Minus); 

ejemplo simple.

http://liveworkspace.org/code/79939893695e40f1761d81ba834c5d15

+0

@ForEverT thanks! funcionó muy bien! –

2

Por desgracia, el idioma no permite que usted utilice la sintaxis para unir un objeto a la función miembro para hacer un objeto invocable. Puede pasar en una referencia de objeto (o puntero) y obligar a éste cuando se llama a la función:

void Will_Get_Function_Pointer(float a, float b, A & obj, float (A::*pt2Func)(float, float)) 
{ 
    (obj.pt2Func)(a,b); 
} 

Will_Get_Function_Pointer(1.00, 2.00, myA, &A::Minus); 

O puede crear un objeto de función que se une el puntero de función al objeto:

void Will_Get_Function(float a, float b, std::function<float(float,float)> f) 
{ 
    f(a,b); 
} 

Will_Get_Function(1.00, 2.00, std::bind(&A::Minus, &myA)); 

Tenga en cuenta que function y bind son nuevos en C++ 11; Boost proporciona equivalentes si está atrapado con una versión anterior del idioma.

+0

+1 para vinculación: esta es a menudo la función de referencia cuando se trata de referencias a funciones. – Marcin

+0

no se puede usar C++ 11 o boost. Pero la sintaxis de enlace es realmente muy agradable. –

2

Use a macro.

#define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember)) 

Situaciones función miembro es simple, ya que already have a typedef para la función que desea llamar.

float result = CALL_MEMBER_FN(*myA, pA)(a, b); 
+0

No se pierda los consejos paralelos de las preguntas más frecuentes para declarar puntos a las funciones miembro: [use un typedef] (http://www.parashift.com/c++faq-lite/typedef-for-ptr-to-memfn. html). –

+0

Supongo que debería ser 'CALL_MEMBER_FN (* myA, pA) (x, y);' dado que, a pesar de su nombre, su macro no hace nada. Personalmente, encontraría '(myA-> pA) (x, y)' bastante más legible que ese lío. –

+0

Whoops, tienes razón, por supuesto. Fijo. –

Cuestiones relacionadas