2010-07-23 48 views
9

Có một lớpC++. phương pháp lớp con trỏ

class A { 
public: 
    A() {}; 

private: 
    void func1(int) {}; 
    void func2(int) {}; 


}; 

Tôi muốn thêm một con trỏ hàm đó sẽ được thiết lập trong constructor và các điểm đến Func1 hoặc Func2.

Vì vậy, tôi có thể gọi con trỏ này (là thành viên của lớp) từ mọi quy trình lớp và đặt con trỏ này trong hàm tạo.

Tôi có thể làm như thế nào?

+3

Tùy thuộc vào mục tiêu của bạn, thừa kế ảo hoặc mẫu có thể phù hợp hơn, FWIW. – Cogwheel

Trả lời

5

Thêm một biến thành viên

void (A::*ptr)(); 

bộ nó trong constructor

ptr=&A::func1; 

(hoặc sử dụng danh sách initializer) và gọi nó là trong phương pháp A:

(this->*ptr)(); 
+0

(điều này -> * ptr)(), không phải điều này -> * ptr() – Tomek

+0

@Tomek: Cảm ơn, đã sửa. – jpalecek

2

Xem boost::function để biết cách xử lý các hàm con trỏ thành viên hàm và lớp theo cách OO/C++.

Ví dụ (từ tài liệu):

struct X 
{ 
    int foo(int); 
}; 

boost::function<int (X*, int)> f; 

f = &X::foo; 

X x; 
f(&x, 5); 
0

Một số ví dụ ...

class A; // forward declaration 
typedef void (A::*func_type)(int); 

class A { 
public: 
    A() { 
    func_ptr = &A::func1; 
    } 

    void test_call(int a) { 
    (this->*func_ptr)(a); 
    } 

private: 
    func_type func_ptr; 

    void func1(int) {} 
    void func2(int) {} 
}; 
+0

(điều này -> * ptr)(), không phải điều này -> * ptr() – Tomek

8
class A { 
public: 
    A(bool b) : func_ptr_(b ? &A::func1 : &A::func2) {}; 

    void func(int i) {this->*func_ptr(i);} 

private: 
    typedef void (A::*func_ptr_t_)(); 
    func_ptr_t_ func_ptr_; 

    void func1(int) {}; 
    void func2(int) {}; 
}; 

Điều đó nói rằng, đa hình có thể là một cách tốt hơn để làm bất cứ điều gì bạn muốn để làm điều này.

+1

Chắc chắn. Đây là cú pháp phức tạp và bất thường vì một lý do. Đây chính xác là vấn đề OO giải quyết dễ dàng. –

+0

Mã không biên dịch (trên XCode ít nhất), bạn khai báo func_ptr_ và sau đó sử dụng func_ptr ... – RelativeGames

+2

@Cippyboy: Tôi thậm chí không chắc chắn về những gì để trả lời. Bạn đã đi đến những rắc rối để downvote và bình luận, nhưng không phải để sửa lỗi này tầm thường ?! Ừm, đoán xem, tôi sẽ để nó ở đó ngay bây giờ, chỉ để mặc kệ bạn thôi. – sbi

2

Tôi đã biên dịch và chạy mã này. Các thành viên khác nhau cần phải được công khai để bạn có thể vượt qua chúng vào constructor. Nếu không, ở đây bạn đi.

Tuy nhiên, tôi đồng ý với các áp phích khác rằng điều này gần như chắc chắn là một điều xấu để làm. ;) Chỉ cần thực hiện gọi virtual virtual, và sau đó tạo hai lớp con của A mà mỗi override invoke().

#include <iostream> 
using namespace std; 

class A; 
typedef void(A::*MyFunc)(int) ; 

class A { 
    public: 

     A() {} 
     A(MyFunc fp): fp(fp) {} 

     void invoke(int a) 
     { 
      (this->*fp)(a); 
     } 

     void func1(int a) { cout << "func1 " << a << endl; } 
     void func2(int a) { cout << "func2 " << a << endl; } 
    private: 

     MyFunc fp; 
}; 

int main() 
{ 
    A* a = new A(& A::func1); 
    a->invoke(5); 
    A* b = new A(& A::func2); 
    b->invoke(6); 
} 
0

Tại sao bạn cho rằng đó là điều xấu. Tôi chỉ cần một con trỏ hàm và tôi không muốn tạo hai lớp con cho việc này. Vậy tại sao nó lại tệ như vậy?

+0

Bạn không phải tạo hai lớp con cho nó, 'A a'; là để định nghĩa một biến của A, và 'a (1, 123)', đó là một cuộc gọi hàm, và đang gọi func1 với tham số đầu vào là 123; chức năng con trỏ chắc chắn có thể xử lý yêu cầu của bạn, nhưng functor là dễ sử dụng hơn và ngữ pháp là thanh lịch. Khi ai đó cần các tính năng phức tạp hơn của các chức năng gọi điện, chẳng hạn như lưu trạng thái hoặc như vậy, họ chắc chắn phải sử dụng các hàm. Nếu bạn nghĩ rằng functor có thể đáp ứng tất cả các yêu cầu của bạn, tôi hoàn toàn OK với điều đó. Tôi không có vấn đề nếu bạn sử dụng C++ là "C với các lớp học" nhưng như một vấn đề của factd, C + + là nhiều hơn thế. – shader

1

tôi đề nghị bạn sử dụng functor (hoặc đối tượng chức năng), chứ không phải là con trỏ hàm, bởi vì trước đây là an toàn hơn, và con trỏ hàm có thể khó khăn hoặc khó khăn khi phải vượt qua một nhà nước vào hoặc ra khỏi chức năng gọi lại

Một functor cơ bản là một tái thực hiện hành() của lớp A, để mô tả rất chi tiết vui lòng tham khảo Wikipedia: http://en.wikipedia.org/wiki/Function_object

mã nên được một cái gì đó như thế này:

class A { 
public: 
    A() {}; 
    void operator()(int function_index, int parameter) { 
    if(function_index == 1) 
     func1(parameter); 
    else if(function_index == 2) 
     func2(parameter); 
    else 
     { //do your other handling operation 
     } 
    } 


private: 
    void func1(int) {}; 
    void func2(int) {}; 
}; 

Bằng cách sử dụng lớp đó:

A a; 
a(1, 123); //calling func1 
a(2, 321); //calling func2 
Các vấn đề liên quan