2010-03-08 57 views
53

Tôi muốn thiết lập một con trỏ hàm làm thành viên của một lớp là con trỏ tới một hàm khác trong cùng một lớp. Lý do tại sao tôi làm điều này rất phức tạp.Hàm con trỏ tới hàm thành viên

Trong ví dụ này, tôi muốn đầu ra được "1"

class A { 
public: 
int f(); 
int (*x)(); 
} 

int A::f() { 
return 1; 
} 


int main() { 
A a; 
a.x = a.f; 
printf("%d\n",a.x()) 
} 

Nhưng điều này không thành công ở biên soạn. Tại sao?

Trả lời

89

Cú pháp sai. Một con trỏ thành viên là một loại thể loại khác với một con trỏ bình thường. Con trỏ thành viên sẽ phải được sử dụng cùng với một đối tượng của lớp học:

class A { 
public: 
int f(); 
int (A::*x)(); // <- declare by saying what class it is a pointer to 
}; 

int A::f() { 
return 1; 
} 


int main() { 
A a; 
a.x = &A::f; // use the :: syntax 
printf("%d\n",(a.*(a.x))()); // use together with an object of its class 
} 

a.x chưa nói về những gì đối tượng chức năng là để được gọi vào. Nó chỉ nói rằng bạn muốn sử dụng con trỏ được lưu trữ trong đối tượng a. Đăng ký a một lần khác với toán hạng bên trái cho toán tử .* sẽ thông báo cho trình biên dịch về đối tượng nào cần gọi hàm trên.

+0

Tôi biết điều này là cũ, nhưng tôi không hiểu việc sử dụng '(a. * A.x)()'. Tại sao '(a. * X)()' không hoạt động? –

+0

@gau vì x không nằm trong phạm vi –

+1

@gau tôi đã thêm parens ngay bây giờ để làm cho nó rõ ràng hơn –

8

Bạn cần sử dụng con trỏ đến hàm thành viên, không chỉ là con trỏ đến hàm.

class A { 
    int f() { return 1; } 
public: 
    int (A::*x)(); 

    A() : x(&A::f) {} 
}; 

int main() { 
    A a; 
    std::cout << (a.*a.x)(); 
    return 0; 
} 
15

int (*x)() không phải là con trỏ tới hàm thành viên. Một con trỏ tới hàm thành viên được viết như sau: int (A::*x)(void) = &A::f;.

5

Call member function on string command

#include <iostream> 
#include <string> 


class A 
{ 
public: 
    void call(); 
private: 
    void printH(); 
    void command(std::string a, std::string b, void (A::*func)()); 
}; 

void A::printH() 
{ 
    std::cout<< "H\n"; 
} 

void A::call() 
{ 
    command("a","a", &A::printH); 
} 

void A::command(std::string a, std::string b, void (A::*func)()) 
{ 
    if(a == b) 
    { 
     (this->*func)(); 
    } 
} 

int main() 
{ 
    A a; 
    a.call(); 
    return 0; 
} 

Chú ý đến (this->*func)(); và cách khai báo con trỏ chức năng với tên lớp void (A::*func)()

0

Trong khi điều này được dựa trên sterling câu trả lời ở đâu đó trên trang này, tôi đã có một trường hợp sử dụng không được chúng giải quyết hoàn toàn; cho một vector của các con trỏ đến chức năng thực hiện như sau:

#include <iostream> 
#include <vector> 
#include <stdio.h> 
#include <stdlib.h> 

class A{ 
public: 
    typedef vector<int> (A::*AFunc)(int I1,int I2); 
    vector<AFunc> FuncList; 
    inline int Subtract(int I1,int I2){return I1-I2;}; 
    inline int Add(int I1,int I2){return I1+I2;}; 
    ... 
    void Populate(); 
    void ExecuteAll(); 
}; 

void A::Populate(){ 
    FuncList.push_back(&A::Subtract); 
    FuncList.push_back(&A::Add); 
    ... 
} 

void A::ExecuteAll(){ 
    int In1=1,In2=2,Out=0; 
    for(size_t FuncId=0;FuncId<FuncList.size();FuncId++){ 
    Out=(this->*FuncList[FuncId])(In1,In2); 
    printf("Function %ld output %d\n",FuncId,Out); 
    } 
} 

int main(){ 
    A Demo; 
    Demo.Populate(); 
    Demo.ExecuteAll(); 
    return 0; 
} 

Something như thế này rất hữu ích nếu bạn đang viết một thông dịch lệnh với chức năng lập chỉ mục mà cần phải được kết hôn với cú pháp tham số và giúp đỡ các mẹo, vv Có thể cũng hữu ích trong menu.

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