2013-01-13 17 views
3

我正在將一些C#代碼轉換爲C++。我最初雖然用C風格的回調替代了代表。然而,對代碼的進一步檢查,本人已認識到,這是行不通的,因爲代表被以多播方式被使用,以(僞C#代碼)等語句:C++中的組播代理

DelegateTypeOne one = new DelegateTypeOne(someCallbackFunc1) 
one += new DelegateTypeOne(someCallbackFunc2) 

我明白如果被移植的代碼以單一轉換方式使用委託,那麼使用常規的C風格函數指針可能已經奏效。關於這一點,我有一個問題,就是下面的C++代碼有效?:

typedef std::vector<int> (CallbackTypeOne*) (const std::string& s, const bool b); 
std::vector<int> foo (const std::string& s, const bool b); 

CallbackTypeOne func_ptr = NULL; 

func_ptr = new CallbackTypeOne(foo); // Note: new being used on a typedef not a type 

// or should I just assign the func the normal way? 
func_ptr = foo; // this is what I am doing at the moment 

我在執行代表將寫一個名爲ABC代表,這將是一個仿原始的想法。所有其他代表將從這個ABC中派生出來,並且他們將有一個STL容器(很可能是一個列表),它將包含所有分配函數的列表,並按順序調用。

這似乎相當多的工作,我甚至不相信它是最合適的方法。有沒有人在此之前完成過這種C#到C++的traqnslation,以及在C++中實現多播委託的推薦方法是什麼?

+1

我會推薦查看Boost庫(www.boost.org)。這在C++中可能是一項複雜的任務。 –

+0

使用'new'來分配'CallBackTypeOne'可能不是你打算做的事情,它也不會產生有效的C++。只需使用'func_ptr = foo;' –

回答

5

我有兩個可能的解決方案建議

  1. 使用函數指針的載體,而不是一個函數指針。限定保持回調的向量,並具有運算符()的調用將調用回調
  2. 使用時boost signals
0

最簡單的方法是使用例如一個類作爲多播委託的支持結構。然而,即使std::function作爲任何可調用類型的包裝,細節可能會相當尷尬,因此我也推薦使用boost::signals ...

3

試試這個多播委託的示例。它假定C++ 11 => gcc 4.7或更高版本。

//////////////////////////////////////////////////////////// 
// 
//  Bind and Function 
// 
//////////////////////////////////////////////////////////// 

#include <vector> 
#include <string> 
#include <iostream> 
#include <functional> 
using namespace std; 


class Greeting 
{ 
public: 
    Greeting(const string& name) : name(name) {} 
    string Hello() { return "Hello " + name; } 
    string Wait() { return "Wait " + name; } 
    string Goodbye() { return "Goodbye " + name; } 
private: 
    string name; 
}; 

template <typename T> 
struct Delegate 
{ 
    vector<T> list; 

    void operator+=(T item) 
    { 
     list.push_back(item); 
    } 

    void operator()() 
    { 
     for(unsigned i = 0; i < list.size(); i++) 
     { 
      T item; 
      item = list[i]; 
      cout << item() << endl; 
     } 
    } 
}; 


////// 

int main() 
{ 
    // create pointer to function objects 
    function<string()> f; 
    Delegate<function<string()>> d; 
    Greeting john("John"); 
    Greeting sue("Sue"); 

    // load up multicast delegate 
    d += bind(&Greeting::Hello, john); 
    d += bind(&Greeting::Goodbye, sue); 
    d += bind(&Greeting::Wait, john); 

    // fire delegate 
    d(); 

    return 0; 
}