2012-09-06 58 views
5

Tôi đang cố gắng làm điều gì đó với con trỏ để hoạt động thành viên mà tôi không thể 'tìm ra cách hoạt động này.con trỏ đến hàm thành viên

Tôi có một lớp A mà trông giống như sau

class A 
{ 
    public: 
    float Plus (float a, float b) { return a+b; } 
    float Minus (float a, float b) { return a-b; } 
    float Multiply(float a, float b) { return a*b; } 
    float Divide (float a, float b) { return a/b; } 
}; 

Tôi muốn khai báo một con trỏ đến A và sau đó vượt qua chức năng khác một con trỏ hàm để một trong những thành viên của A.

Một cái gì đó thích này:

void Will_Get_Function_Pointer(float a, float b, float (A::*pt2Func)(float, float)) 
{ 
    (...) 
} 

đâu tôi sẽ gọi nó với một cái gì đó như thế này

A* myA = new A; 
Will_Get_Function_Pointer(1.00,2.00, &myA->Minus) 

tôi không thể sử dụng tĩnh/thành viên const vì Thực hiện cuối cùng của tôi A sẽ trỏ đến một Một cụ thể trong một bộ sưu tập của A đối tượng trong cái gì đó sẽ trông như thế này

vector<A> vecA; 
myA = &vecA[xxx] 

Việc làm này thất bại thảm hại

typedef float (A::*pA)(float x, float y); 
pA p = &myA->Minus; 

và trình biên dịch yêu cầu tôi sử dụng & A :: Trừ nhưng điều đó sẽ không hiệu quả đối với tôi.

Tôi thậm chí có thể thực hiện việc này không?

Cheers

Trả lời

6
A* myA = new A; 
Will_Get_Function_Pointer(1.00,2.00, &myA->Minus) 

Bạn không thể. Bạn nên sử dụng một cái gì đó giống như

void Will_Get_Function_Pointer(A* object, float a, float b, 
float (A::*pt2Func)(float, float)) 
{ 
    (object->*pt2Func)(a, b); 
} 

Và gọi nó như

A* myA = new A; 
Will_Get_Function_Pointer(myA, 1.00, 2.00, &A::Minus); 

Ví dụ đơn giản.

http://liveworkspace.org/code/79939893695e40f1761d81ba834c5d15

+0

@ForEverT cảm ơn! nó hoạt động rất tốt! –

2

Thật không may, ngôn ngữ không cho phép bạn sử dụng cú pháp đó để ràng buộc một đối tượng đến chức năng thành viên để thực hiện một đối tượng có thể được gọi. Bạn có thể vượt qua trong một tham chiếu đối tượng (hoặc con trỏ) và ràng buộc nó khi bạn gọi hàm:

void Will_Get_Function_Pointer(float a, float b, A & obj, float (A::*pt2Func)(float, float)) 
{ 
    (obj.pt2Func)(a,b); 
} 

Will_Get_Function_Pointer(1.00, 2.00, myA, &A::Minus); 

Hoặc bạn có thể tạo một đối tượng chức năng gắn kết các con trỏ hàm để các đối tượng:

void Will_Get_Function(float a, float b, std::function<float(float,float)> f) 
{ 
    f(a,b); 
} 

Will_Get_Function(1.00, 2.00, std::bind(&A::Minus, &myA)); 

Lưu ý rằng functionbind là mới trong C++ 11; Boost cung cấp tương đương nếu bạn đang mắc kẹt với một phiên bản cũ của ngôn ngữ.

+0

+1 cho liên kết - đây thường là chức năng go-to khi xử lý các tham chiếu đến các hàm. – Marcin

+0

không thể sử dụng C++ 11 hoặc tăng. Nhưng cú pháp ràng buộc thực sự rất hay. –

2

Use a macro.

#define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember)) 

Gọi hàm thành viên của bạn là đơn giản bởi vì bạn already have a typedef cho chức năng bạn muốn gọi.

float result = CALL_MEMBER_FN(*myA, pA)(a, b); 
+0

Đừng bỏ lỡ lời khuyên song song của FAQ để khai báo các điểm cho các hàm thành viên: [sử dụng typedef] (http://www.parashift.com/c++-faq-lite/typedef-for-ptr-to-memfn. html). –

+0

Tôi giả định rằng nên là 'CALL_MEMBER_FN (* myA, pA) (x, y);' kể từ khi, mặc dù tên của nó, macro của bạn không phải tất cả mọi thứ. Cá nhân, tôi muốn tìm '(myA-> pA) (x, y)' khá dễ đọc hơn là mớ hỗn độn đó. –

+0

Rất tiếc, bạn hoàn toàn đúng. Đã sửa. –

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