2013-05-14 46 views
1

我在C++中使用函數數組的經驗並不多。我需要使用一個函數數組,其中數組包含來自不同對象的函數。 下面是一些虛擬代碼來說明我想要實現的內容。具有不同對象功能的函數陣列

class base_class 
{ 
public: 
    virtual int function1(int arg1, int arg2); 
    virtual int function2(int arg1, int arg2); 
}; 

class derived_class : public base_class 
{ 
public: 
    int function1(int arg1, int arg2) { /* ... */ }; 
    int function2(int arg1, int arg2) { /* ... */ }; 
    // ... 
}; 

typedef int (*functions) (int arg1, int arg2); 

int main() 
{ 
    derived_class object1; 
    derived_class object2; 

    functions func_instance[4]; 
    func_instance[0] = object1.function1; 
    func_instance[1] = object1.function2; 
    func_instance[2] = object2.function1; 
    func_instance[3] = object2.function2; 
    // ... 
} 

我無法得到它的工作,它拋出以下錯誤:

error: argument of type int() (int , int) does not match int (*) (int, int) 
+2

查一查'的std :: function'和'的std :: bind'。 – Antimony 2013-05-14 07:16:24

+0

歡迎來到SO。請查看http://stackoverflow.com/faq瞭解網站的工作原理。請將您的問題的最佳答案標記爲已接受並相應地進行投票。玩得開心:) – pmr 2013-05-14 21:52:39

回答

9

最簡單的方法是使用std::functionstd::bind

#include <functional> 
#include <array> 

derived_class object1; 
derived_class object2; 

std::array< std::function<int(int, int)>, 2> > 
    arr = {{ std::bind(&derived_class::function1, &object1) 
     , std::bind(&derived_class::function2, &object1)}}; 
     // and so on 

注意object1object2已通過地址綁定。只要綁定的函數存在,就需要讓它們保持活躍狀態​​。如果只在bind表達式中寫入object1,則該對象的副本將存儲在綁定函數中,並且不會發生範圍問題。

C++ 03與手卷,單一用途的粘合劑型一個完整的例子:

#include <iostream> 

struct base 
{ 
    virtual void f0() { std::cout << "f0 base" << std::endl; } 
    virtual void f1() { std::cout << "f1 base" << std::endl; } 
}; 

struct derived : base 
{ 
    void f0() { std::cout << "f0 derived" << std::endl; } 
    void f1() { std::cout << "f1 derived" << std::endl; } 
}; 

// typedef for a Pointer to a member function 
// of base that accepts arguments and returns void 
typedef void (base::*MemberPtrType)(void); 

// we pack a pointer to a class and a pointer to a member function together 
struct binder 
{ 
    MemberPtrType ptr; 
    base*   base; 

    // shortcut to call this thing, you might also want 
    // to have an overload of operator() and a result_type typedef 
    void call() 
    { ((base)->*(ptr))(); } 
}; 


int main() 
{ 
    base b; 
    derived d; 

    // initialize a 4 element array of binder, the first argument is the function, 
    // the second is the object to call it on 
    // 
    // remember that b and d need to be alive as long as 
    // you want to call something in this array 
    binder arr[4] = { {&base::f0, &b}, {&base::f1, &b}, 
        {&base::f0, &d}, {&base::f1, &d}}; 

    // now walk through the array and call each 
    for(binder* begin = arr; begin != arr + 4; ++begin) 
    { 
    begin->call(); 
    } 


    return 0; 
} 
+0

感謝您的建議,我試着採用這個,GCC 4.1.2沒有'數組'標頭(?)。我必須使用這個編譯器。有其他解決方案嗎? – functon 2013-05-14 08:09:48

+0

@functon它也不會有'功能'。您的選擇包括使用Boost庫或以痛苦的方式進行。我試圖想出一個C++ 03解決方案。但是那些編寫和維護可能會比較困難,然後根本就沒有這樣做...... – pmr 2013-05-14 08:11:17

+0

@functon我加了一個C++ 03的例子。 – pmr 2013-05-14 08:22:07

相關問題