2011-10-20 25 views
6

favor considerar estos archivos:Referencia no definida al miembro indicador de función estática en C++, ¿qué estoy haciendo mal?

ph:

#ifndef _p_h_ 
#define _p_h_ 

class p{ 
public:  
    static void set_func(int(*)()); 

private: 
    static int (*sf)(); 

}; 
#endif 

p.cpp:

#include "p.h" 
#include <cstdio> 

int (p::*sf)() = NULL; //defining the function pointer 

void p::set_func(int(*f)()){ 
    sf = f; 
} 

main.cpp:

#include "p.h" 
#include <iostream> 

int function_x(){ 
     std::cout << "I'm function_x()" << std::endl; 
     return 1234; 
} 

int main(){ 
     p::set_func(function_x); 
} 

al compilar, me sale esto:

$ g++ -o pp main.cpp p.cpp 
/tmp/ccIs0M7r.o:p.cpp:(.text+0x7): undefined reference to `p::sf' 
collect2: ld returned 1 exit status 

pero:

$ g++ -c -o pp p.cpp 

compila derecha.

¿Qué pasa con el código? Simplemente no puedo encontrar dónde está el problema, por favor su ayuda será más que apreciada.

Gracias.

+0

Puede considerar usando [Boost.Function] (http://www.boost.org/doc/libs/1_47_0/doc/html/function.html). –

Respuesta

12

su intento de definir p::sf es incorrecta – la suya es una definición de una variable global llamada sf que es de tipo int (p::*)(), es decir, un puntero a una función miembro. En consecuencia, p::sf permanece indefinido, de ahí el error del enlazador.

probar este lugar:

int (*p::sf)() = 0; 

// or, 

typedef int (*p_sf_t)(); 
p_sf_t p::sf = 0; 
+0

¡Guau, muchas gracias por esa explicación! ahora entiendo mejor cómo funciona el operador "::". – Auxorro

4

La diferencia se debe a que el error sólo se produce cuando en realidad se vincula al programa. El problema está en su declaración del puntero de la función estática. La sintaxis correcta es:

int (*p::sf)() = NULL; //defining the function pointer 
+0

muchas gracias, funcionó – Auxorro

3

se define un puntero a función miembro y no un puntero de función. No estoy seguro de lo que la sintaxis correcta es, pero me hubiera intentado algo como esto:

int (*p::sf)() = NULL; 
+0

muchas gracias, funcionó – Auxorro

1

No voy a dar otra respuesta (respuesta Ildjarn es correcta), pero voy a sugerir otra forma de lograr el mismo sin inicialización estática (y las cargas que ello implica)

class p{ 
public: 
    typedef int (*func_t)(); 
    static void set_func(func_t v) { 
     func_t& f = getFuncRef(); 
     f = v; 
    } 

    static void call_func() { 
     func_t& f = getFuncRef(); 
     assert(f != 0); 
     f(); 
    } 

private: 

    static func_t& getFuncRef() { 
    static func_t sf = 0; 
    return sf; 
    } 

}; 

en esta forma de delegar la inicialización estática a una variable de función estática, que no tiene los problemas de orden de inicialización de las variables que afectan de datos estáticos, y es lazy- inicializado

Cuestiones relacionadas