2010-07-23 107 views
9

有一類C++。類方法指針

class A { 
public: 
    A() {}; 

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


}; 

我想補充一個函數指針將在構造函數和點被設置爲FUNC1或FUNC2。

所以我可以從每個類過程調用該指針(作爲類成員),並在構造函數中設置此指針。

我該怎麼辦?

+3

根據您的目標,虛擬繼承或模板可能更合適,FWIW。 – Cogwheel 2010-07-23 15:08:03

回答

5

添加一個成員變量

void (A::*ptr)(); 

集它在構造

ptr=&A::func1; 

(或使用初始化列表),並調用它在A的方法:

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

(this - > * ptr)(),not this - > * ptr() – Tomek 2010-07-23 20:33:52

+0

@Tomek:謝謝,糾正。 – jpalecek 2010-07-23 21:27:18

2

boost::function用於以更多OO/C++方式處理函數和類成員指針的方法。

例如(從文件):

struct X 
{ 
    int foo(int); 
}; 

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

f = &X::foo; 

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

一些例子...

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

(this - > * ptr)(),不是 - > * ptr() – Tomek 2010-07-23 20:35:32

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) {}; 
}; 

這就是說,多態性可能是一個更好的方式做任何你想要的與此相關。

+1

當然。這是棘手和不尋常的語法的原因。這正是OO容易解決的問題。 – 2010-07-23 15:18:20

+0

代碼不能編譯(至少在XCode上),你聲明瞭func_ptr_,然後使用了func_ptr ... – RelativeGames 2013-03-21 21:03:44

+2

@Cippyboy:我甚至不知道該怎麼回答。你去麻煩了downvote和評論,但不是解決這個微不足道的錯誤?!那麼,猜猜看,我現在就把它放在那裏,只是爲了詛咒你。 – sbi 2013-03-23 22:04:21

2

我編譯並運行了這段代碼。各種成員需要公開,所以你可以將它們傳遞給構造函數。否則,在這裏你去。

但是,我同意其他海報,這幾乎肯定是一件壞事。 ;)只需調用純虛擬,然後創建A的兩個子類,每個子類重寫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

你爲什麼認爲這是一件壞事。我只需要一個函數指針,我不想爲此創建兩個子類。那爲什麼這麼糟糕?

+0

您不必爲它創建兩個子類'A a';是定義A的一個變量,'a(1,123)',這是一個函數調用,並且調用func1,輸入參數爲123;函數指針肯定可以處理你的請求,但函子更容易使用,語法優雅。當有人需要調用函數更復雜的功能時,例如保存狀態等,他們肯定必須使用函子。如果你認爲仿函數可以滿足你的所有要求,那我完全可以。如果您將C++用作「帶類的C」,那麼我沒有問題,但事實上,C++遠不止於此。 – shader 2010-07-23 16:24:33

1

我建議你使用仿函數(或函數對象),而不是函數指針,因爲前者是更安全,函數指針可能是困難的或尷尬的狀態進入或退出回調函數的

一仿函數基本上是一個重新實現類A,運營商()的非常詳細的描述請參見維基百科:http://en.wikipedia.org/wiki/Function_object

代碼應該是這樣的:

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) {}; 
}; 

通過使用類:

A a; 
a(1, 123); //calling func1 
a(2, 321); //calling func2