2011-10-20 15 views
6

perche questi file:Riferimento indefinito al membro del puntatore a funzione statica in C++, cosa sto facendo male?

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); 
} 

durante la compilazione, ottengo questo:

$ 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 

ma:

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

compila destra.

Cosa c'è che non va nel codice? Non riesco a trovare il problema, per favore il tuo aiuto sarà più che apprezzato.

Grazie.

+0

Si potrebbe considerare utilizzando [Boost.Function] (http://www.boost.org/doc/libs/1_47_0/doc/html/function.html). –

risposta

12

Il tuo tentativo di definire p::sf è corretto – la vostra è una definizione di una variabile globale chiamata sf che è di tipo int (p::*)(), vale a dire un puntatore a una funzione di membro. Di conseguenza, p::sf rimane indefinito, quindi l'errore del linker.

Prova a modificare:

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

// or, 

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

Wow, grazie mille per questa spiegazione! ora capisco meglio come funziona l'operatore "::". – Auxorro

4

La differenza è che l'errore si verifica solo quando effettivamente collegare il programma. Il problema è nella dichiarazione del puntatore della funzione statica. La sintassi corretta è:

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

grazie mille, ha funzionato – Auxorro

3

Si definisce un puntatore di funzione membro e non un puntatore di funzione. Non sono sicuro di quello che la sintassi corretta è, ma avrei provato qualcosa di simile:

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

grazie mille, ha funzionato – Auxorro

1

Non voglio dare un'altra risposta (risposta Ildjarn è corretto), ma io vi suggerisco di un altro modo di raggiungere lo stesso senza inizializzazione statica (e gli oneri che essa comporta)

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; 
    } 

}; 

in questo modo si delega l'inizializzazione statica a una variabile funzione statica, che non presenti i problemi di ordine inizializzazione che influenzano le variabili di dati statici, ed è lazy- inizializzato

Problemi correlati