C ++中的多播委托

时间:2013-01-13 12:14:45

标签: c# 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

我对实现代表的最初想法是编写一个名为Delegate的ABC,它将是一个仿函数。所有其他代表都将从这个ABC派生,他们将有一个STL容器(很可能是一个列表),它将包含一个按顺序调用的任何已分配函数的列表。

这似乎是相当多的工作,我甚至不相信它是最合适的方法。有没有人之前做过这种C#到C ++的traqnslation,以及在C ++中实现多播委托的推荐方法是什么?

3 个答案:

答案 0 :(得分:5)

我有两个可能的解决方案提案

  1. 使用函数指针的向量,而不是函数指针。定义一个包含回调向量的类,并且具有operator(),当调用它时将调用回调
  2. 使用boost signals

答案 1 :(得分:3)

尝试使用此多播委托示例。它假设C ++ 11 =&gt; 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;
}

答案 2 :(得分:0)

最简单的方法是使用例如std::vector< std::function<TSignature> >作为多播委托的支持结构。但是,即使std::function作为任何可调用类型的包装器,细节也会变得非常笨拙,因此我也建议使用boost::signals ...