3

我正在使用旧版 C 库进行网络连接。例如,它允许我创建一个套接字服务器。我必须将函数指针传递给库以处理协议 - 例如处理消息结构、标头长度等。

在 C 程序中,您只需将指针传递给函数,例如get_protocol. 但是这样做的OO方式是什么。

我有一个包装类,我们称之为socket_server。我希望能够在运行时传递不同协议所需的函数指针。

我怎么做?这是策略模式解决的问题吗?

编辑

我喜欢 std::function 的想法,但我们暂时停留在 VS2008 上,所以 C++11 还没有对我开放。

4

4 回答 4

2

使用std::function

class Test
{
    std::function<void()> func;
public:
    Test(const std::function<void()> &func) : func(func) {}

    void do_something()
    {
        func();
    }
};

void my_func()
{
    std::cout << "Hello" << std::endl;
}

int main()
{
    Test test(my_func);
    test.do_something();
}

基于模板

template <typename Func>
class Test
{
    Func *func;
public:
    Test(const Func &func) : func(func) {}

    void do_something()
    {
        func();
    }
};

void my_func()
{
    std::cout << "Hello" << std::endl;
}

int main()
{
    Test<void()> test(my_func);
//  Test<decltype(my_func)> test(my_func); // This is even better
    test.do_something();
}
于 2013-04-17T14:43:22.800 回答
1

正如评论者建议的那样,您应该使用 C++11 新功能std::function

就个人而言,在 C++03 中,我已经很喜欢函子了。整个<algorithm>标题都是亲函子,(当然现在是 C++11 std::function

仿函数是一个覆盖 的对象,operator()您可以调用它()来执行此类函数。

您可以将其operator()视为“perform()”函数,就像简化的单一策略一样。

struct Functor
{
    void operator()(int param_a, const string& param_b)
    {
          // perform what you want
    }
    int my_member;
}

Functor f;
f(0,"go_std_function")

但除非你有充分的理由,否则请选择std::function. 它是手工仿函数的概括,也是经典函数:任何可调用的函数:-)。

于 2013-04-17T14:48:24.973 回答
0

如果我理解正确的话。这是你需要做的:

在您的头文件中,创建一个要作为静态传递的函数。例如:

static void* ThreadWorker(void* worker);

在您的源文件中,您可以这样称呼它:

pthread_create(&thread, NULL, ThreadWorker, (void *) worker);

该函数必须是静态的,因为编译器不知道哪个实例正在调用它。但我相信有人可以更好地解释它。

于 2013-04-17T14:40:53.860 回答
0

执行此操作的“OO C”方式也是传递一个void *值以允许将某些上下文传递给回调函数。传递的实际值将是指向回调函数可以理解的某种类型的指针struct(在转换回真实类型之后)。这不是类型安全的,但它在实践中工作得非常好,并且struct可以轻松地保存指向 C++ 对象的指针,从而允许将 thunk 关闭为一个健全的 API。

如果没有这样的指针,您实际上只能调用静态方法作为回调(或将对象引用放在全局变量中,这确实很讨厌!)当然,此时它不再是真正的 OO C 接口要么,而是一些讨厌的东西,考虑重写或切换到在其他东西之上构建变得理智。

于 2013-04-17T16:16:30.583 回答