2011-10-20 9 views
6

Proszę rozważyć te pliki:Niezdefiniowane odniesienie do elementu wskaźnika funkcji statycznej w języku C++, co robię źle?

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

podczas kompilacji, uzyskać to:

$ 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 

ale:

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

kompiluje prawo.

Co jest nie tak z kodem? Po prostu nie mogę znaleźć problemu, proszę, twoja pomoc będzie bardziej niż doceniona.

Dzięki.

+0

Możesz rozważyć za pomocą [Boost.Function] (http://www.boost.org/doc/libs/1_47_0/doc/html/function.html). –

Odpowiedz

12

Twoja próba zdefiniowania p::sf jest nieprawidłowy – twój jest definicja zmiennej globalnej o nazwie sf, który jest typu int (p::*)(), czyli wskaźnik do funkcji składowej. W związku z tym p::sf pozostaje niezdefiniowany, stąd błąd łącznika.

Spróbuj to zamiast:

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

// or, 

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

Wow, Wielkie dzięki za wyjaśnienie! teraz lepiej rozumiem, jak działa operator "::". – Auxorro

4

Różnica polega na tym, ponieważ błąd występuje tylko wtedy, gdy rzeczywiście odwołuje się program. Problem leży w deklaracji wskaźnika funkcji statycznej. Poprawna składnia to:

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

dziękuję, zadziałało – Auxorro

3

Definiujesz wskaźnik funkcji członka, a nie wskaźnik funkcji. Nie jestem pewien, co składnia jest poprawna, ale bym spróbował coś takiego:

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

wielkie dzięki, zadziałało – Auxorro

1

nie dam kolejną odpowiedź (Ildjarn odpowiedź jest prawidłowa), ale zaproponuje Ci inny sposób osiągnięcia tego samego bez inicjalizacji statycznej (i obciążeń to wskazuje)

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

}; 

w ten sposób przekazać statycznej inicjalizacji statycznej zmiennej funkcji, które nie mają problemów, które wpływają na kolejność inicjalizacji zmiennych statycznych danych i jest lazy- zainicjowano:

Powiązane problemy