4

我正在将一些 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++ 的转换,在 C++ 中实现多播委托的推荐方法是什么?

4

3 回答 3

5

我有两个可能的解决方案建议

  1. 使用函数指针向量,而不是函数指针。定义一个类,该类包含一个回调向量并具有 operator(),在调用时将调用回调
  2. 使用升压信号
于 2013-01-13T12:18:44.520 回答
4

试试这个多播委托的例子。它假定 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;
}
于 2013-10-14T22:02:49.990 回答
0

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

于 2013-01-13T14:11:58.887 回答