2013-02-11 52 views
16

Tôi có một danh sách các con trỏ cho các hàm thành viên nhưng tôi đang gặp khó khăn khi cố gắng gọi những hàm đó ... cú pháp thích hợp là gì?C++ Gọi con trỏ tới chức năng thành viên

typedef void (Box::*HitTest) (int x, int y, int w, int h); 

for (std::list<HitTest>::const_iterator i = hitTestList.begin(); i != hitTestList.end(); ++i) 
{ 
    HitTest h = *i; 
    (*h)(xPos, yPos, width, height); 
} 

Cũng im cố gắng để thêm chức năng thành viên để nó ở đây

std::list<HitTest> list; 

for (std::list<Box*>::const_iterator i = boxList.begin(); i != boxList.end(); ++i) 
{ 
    Box * box = *i; 
    list.push_back(&box->HitTest); 
} 
+0

xác định "gặp khó khăn" –

+2

Không hoạt động lol và tôi không thể làm việc đó – ThingWings

+0

Bạn có chắc chắn muốn thực hiện theo cách này và không sử dụng danh sách các phần tử Hộp và chức năng ảo không? –

Trả lời

24

Pointers cho các thành viên là một con quái vật độc đáo với cú pháp độc đáo.

Bạn phải có con trỏ Box tiện dụng sẽ được sử dụng làm this.

(box->*h)(xPos, yPos, width, height); 
+0

Tôi nhận được lỗi "Lỗi: Biểu thức phải có loại con trỏ" với cú pháp đó – ThingWings

+0

@JC. Ở đây, hãy thử điều này: http://www.parashift.com/c++-faq/macro- for-ptr-to-memfn.html –

+0

Giống như '((* this). * h) (xPos, yPos, width, height)' nhưng tôi muốn tránh xa – sehe

7

Gọi một hàm thành viên thông qua một con trỏ tới hàm thành viên có một cú pháp đặc biệt:

(obj.*pmf)(params); // Through an object or reference. 
(ptr->*pmf)(params); // Through a pointer. 

Mặc dù ->* thể được ghi đè, nó không phải là trong tiêu chuẩn lặp thư viện (có lẽ vì nó sẽ yêu cầu ghi đè cho mọi loại chức năng có thể). Vì vậy, nếu tất cả các bạn đã có được một iterator , bạn sẽ phải dereference nó và sử dụng các hình thức đầu tiên:

((*iter).*pmf)(params); 

Mặt khác, lặp lại trên một con trỏ đến các thành viên mình không có vấn đề này:

(objBox.*(*i))(params); // If Box is an object 
(ptrBox->*(*i))(params); // If Box is a pointer 

(tôi không nghĩ rằng bạn cần ngoặc xung quanh *i, nhưng con trỏ cú pháp thành viên đã đủ đặc biệt.)

5

Từ của tôi "đoạt giải thưởng" ;-) trả lời er về đại biểu (có sẵn tại https://stackoverflow.com/questions/9568150/what-is-a-c-delegate/9568226#9568226):

typedef con trỏ tới hàm thành viên như thế này:

typedef void (T::*fn)(int anArg); 

Khai báo một như thế này:

fn functionPtr = &MyClass::MyFunction 

Gọi nó như thế này:

(MyObject.*functionPtr)(argument); 
0

Nỗ lực của bạn để nhận con trỏ hàm thành viên thông qua phản đối đối tượng một sự hiểu lầm. Các con trỏ hàm thành viên không bao gồm một con trỏ tới đối tượng mà bạn gọi chúng. Bạn phải cung cấp một con trỏ như vậy tại điểm của cuộc gọi.

Như nhiều người đã chỉ ra, cú pháp cho một cuộc gọi hàm thành viên là một trong hai:

obj.*funcptr(args); 

hoặc

objptr->*funcptr(args); 

Trong ví dụ bạn đã đưa ra, có vẻ như những gì bạn thực sự cần là một hàm ảo. Bạn có một hoạt động tiêu chuẩn (phát hiện thời tiết hoặc không phải là một đối tượng giao cắt với một hộp) mà cần phải được gọi trên nhiều loại đối tượng khác nhau, loại không thể biết tại thời gian biên dịch. Đây là một công việc được cắt ra cho các chức năng ảo.

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