2009-12-18 39 views
10

Tôi đang gặp lỗi biên dịch (MS VS 2008) mà tôi không hiểu. Sau khi lộn xộn với nó trong nhiều giờ, tất cả đều mờ và tôi cảm thấy như có điều gì đó rất rõ ràng (và rất ngu ngốc) mà tôi đang thiếu. Đây là mã thiết yếu:Làm cách nào để gọi hàm con trỏ thành thành viên?

typedef int (C::*PFN)(int); 

struct MAP_ENTRY 
    { 
    int id; 
    PFN pfn; 
    }; 

class C 
    { 
    ... 
    int Dispatch(int, int); 
    MAP_ENTRY *pMap; 
    ... 
    }; 

int C::Dispatch(int id, int val) 
    { 
    for (MAP_ENTRY *p = pMap; p->id != 0; ++p) 
     { 
     if (p->id == id) 
      return p->pfn(val); // <--- error here 
     } 
    return 0; 
    } 

Trình biên dịch tuyên bố tại mũi tên "thuật ngữ không đánh giá đối số tham gia 1 đối số". Tại sao không? PFN được prototyped như một hàm lấy một đối số, và MAP_ENTRY.pfn là một PFN. Tôi đang thiếu gì ở đây?

+0

Cú pháp C bị gỉ, do đó không được thêm vào làm câu trả lời, nên không được trả về (* (p-> pfn)) (val); "? - –

+0

Không, điều đó tạo ra lỗi "* bất hợp pháp trên các toán hạng của loại C :: PFN". – chrisd

+0

có thể trùng lặp của [Gọi phương thức lớp C++ thông qua một con trỏ hàm] (http://stackoverflow.com/questions/1485983/calling-c-class-methods-via-a-function-pointer) –

Trả lời

17

p->pfn là con trỏ của loại hàm con trỏ tới thành viên. Để gọi một hàm thông qua con trỏ như vậy, bạn cần sử dụng toán tử ->* hoặc toán tử .* và cung cấp đối tượng thuộc loại C làm toán hạng bên trái. Bạn đã không.

Tôi không biết mà đối tượng của loại C là vụ phải được sử dụng ở đây - chỉ có bạn biết điều đó - nhưng trong ví dụ của bạn nó có thể là *this. Trong trường hợp đó các cuộc gọi có thể trông như sau

(this->*p->pfn)(val) 

Để làm cho nó trông một chút ít phức tạp, bạn có thể giới thiệu một biến trung gian

PFN pfn = p->pfn; 
(this->*pfn)(val); 
+0

Cảm ơn. Bây giờ tôi không chỉ có sự điều chỉnh, tôi hiểu tại sao. – chrisd

8

Hãy thử

return (this->*p->pfn)(val); 
+0

YES !! Đó là nó. Cám ơn rất nhiều. Các bạn không thể tin được. Tôi hơi say với điều này trong nhiều giờ và nhận được câu trả lời trong chưa đầy 10 phút. – chrisd

-1

p-> PFN là một con trỏ hàm. Bạn cần sử dụng * để làm cho nó hoạt động. Thay đổi thành

(*(p->pfn))(val) 
0

Làm cho mình một đặc ân và sử dụng boost::function (và tăng :: ràng buộc quá!)

+9

"Xe đạp của tôi xuất phát từ đâu?" - "Tự làm ơn - mua một chiếc máy bay" –

0

điều này không trả lời câu hỏi của bạn, nhưng hãy cân nhắc việc sử dụng hàm boost :: function and boost :: bind. Nó giới thiệu một sự phụ thuộc khá lớn vào codebase của bạn, nhưng nó cũng có giá trị cho các dự án lớn hơn.

1

Chỉ cần để kêu vang trong với kinh nghiệm của riêng tôi, tôi đã đi qua một lỗi trong g ++ gây ra bởi tuyên bố này:

(this -> *stateHandler)() ; 

đâu stateHandler là một con trỏ tới một hàm khoảng trống thành viên của lớp được tham chiếu bởi * điều này. Vấn đề là do không gian giữa các nhà điều hành mũi tên. Đoạn mã sau biên dịch tốt:

(this->*stateHandler)() ; 

Tôi đang sử dụng g ++ (GCC) 4.4.2 20090825 (phát hành lại). FWIW.

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