2011-10-20 21 views
6

hãy xem xét những tập tin này:Không xác định tham chiếu đến thành viên trỏ hàm tĩnh trong C++, tôi đang làm gì sai?

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

khi biên dịch, tôi có được điều này:

$ 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 

nhưng:

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

biên dịch đúng.

Có vấn đề gì với mã? Tôi chỉ không thể tìm ra nơi mà vấn đề là, xin vui lòng giúp đỡ của bạn sẽ được nhiều hơn đánh giá cao.

Cảm ơn.

+0

Bạn có thể xem xét sử dụng [Boost.Function] (http://www.boost.org/doc/libs/1_47_0/doc/html/function.html). –

Trả lời

12

Nỗ lực của bạn khi xác định p::sf không chính xác – là định nghĩa của biến toàn cục có tên là sf thuộc loại int (p::*)(), tức là con trỏ đến hàm thành viên. Do đó, p::sf vẫn không được xác định, do đó lỗi liên kết.

Hãy thử điều này thay vì:

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

// or, 

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

Wow, Cảm ơn rất nhiều vì lời giải thích đó! bây giờ tôi hiểu rõ hơn cách hoạt động của toán tử "::". – Auxorro

4

Sự khác biệt là vì lỗi chỉ xảy ra khi bạn thực sự liên kết các chương trình. Vấn đề là trong khai báo của bạn về con trỏ hàm tĩnh. Cú pháp chính xác là:

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

cảm ơn rất nhiều, nó đã làm việc – Auxorro

3

Bạn xác định con trỏ hàm thành viên chứ không phải con trỏ hàm. Tôi không chắc chắn những gì các cú pháp chính xác là, nhưng tôi sẽ cố gắng một cái gì đó như thế này:

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

cảm ơn rất nhiều, nó đã hoạt động – Auxorro

1

tôi sẽ không cung cấp câu trả lời khác (ildjarn câu trả lời là đúng), nhưng tôi sẽ đề nghị bạn một cách khác để đạt được cùng mà không cần khởi tạo tĩnh (và những gánh nặng nó ngụ ý)

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

}; 

theo cách này bạn ủy nhiệm việc khởi tạo tĩnh để một biến chức năng tĩnh, mà không có những vấn đề trật tự khởi tạo ảnh hưởng đến các biến dữ liệu tĩnh, và là lazy- được khởi tạo

Các vấn đề liên quan