【问题标题】:passing functions传递函数
【发布时间】:2011-04-16 15:27:53
【问题描述】:

好吧,我已经有一段时间没有用 C++ 编写了。 而且我从来没有做过这么高水平的安静的事情。

所以基本上我需要创建一个类。 类的构造函数需要引用(或指针)指向另一个类的方法或函数。

基本上,我有一个类需要偶尔从 fltk 评估器(版本 1.1.x)读取值,然后更改一些关于自身的内容。 每个对象都有自己的评估器与之关联。 (它们还有一个指向同一个父对象的另一个对象的链接,在从评估器更新它们后会告诉它们更新,依此类推)

那么我如何在构造函数中传递函数呢?

【问题讨论】:

  • 你怎么知道在哪个对象上调用传递的方法?该对象是在构造过程中已知的,还是稍后您想要调用它时已知的?
  • 传递的方法不带参数。它只返回一个双精度值,这是评估器当前设置的值。已经创建了具有我要传递的方法的 Valuator 对象。
  • 查看标准函数 mem_fun 和 mem_fun_ref。这些可能完全符合您的要求。
  • 我认为如果您发布一些代码将是一个好主意。然后我们可以提供更具体的帮助。
  • 1.对于应该以 OO 方式解决的问题(从公共根、策略模式或其他少数几个类继承)似乎是不自然的程序方式 2. 代码

标签: c++ function function-pointers arguments fltk


【解决方案1】:

这是一个示例,其中Foo 的方法被传递给Bar 构造函数,然后在给定的Bar 对象上调用:

struct Foo
{
    int z;

    int add(int x, int y)
    {
        return x + y + z;
    }

    int mul(int x, int y)
    {
        return x * y * z;
    }
};

typedef int (Foo::*foo_method)(int, int);

struct Bar
{
    foo_method m;

    Bar(foo_method m) : m(m) {}

    int call_on(Foo* foo)
    {
        return (foo->*m)(4, 2);
    }
};

int main()
{
    Bar bar(&Foo::add);

    Foo foo = { 123 };
    bar.call_on(&foo);
}

另一方面,如果您在Bar 构造时间已经知道Foo 对象,那么Bar 并不真正关心该方法属于哪个类。它所需要的只是一个稍后调用的函子,Foo 对象可以简单地被客户端绑定。

#include <functional>

struct Bar
{
    std::function<int (int, int)> f;

    Bar(std::function<int (int, int)> f) : f(f) {}

    int call()
    {
        return f(4, 2);
    }
};

using namespace std::placeholders;

int main()
{
    Foo foo = { 123 };
    Bar bar(std::bind(&Foo::add, &foo, _1, _2));

    bar.call();
}

如果您没有 C++0x 编译器,请将 std::bind 替换为 std::tr1::bindboost::bind

【讨论】:

  • 是后一种情况,不幸的是我被 GCC 3.42 困住了。 (dev c++),我不想更新,因为这也是我的评估员将使用的。我想我会携带整个对象只是为了访问它的方法。
  • @Oxi:那么Bar 在编译时知道要调用哪个Foo 方法吗?在这种情况下,您根本不需要函数指针。
【解决方案2】:

捕获此问题的最简单方法是使用boost::function。它可以存储函数指针,也可以存储成员函数与对象绑定的结果。

例如,

class Foo {
  Foo(boost::function<int(void)>);
};

将允许您接受任何整数来源。

【讨论】:

    【解决方案3】:

    您的构造函数可能如下所示:

    
    // convenient typedef. This is for a pointer to a function in Foo
    // The function returns void and takes no parameters.
    typedef void (Foo::*FooPtr)();
    
    class Bar {
    public:
       Bar (FooPtr foo_ptr);
    };
    
    

    查看一些网络参考以获取有关指向成员的语法的更多详细信息。如果你先熟悉它会容易得多。

    作为附加说明,请查看函数 mem_fun 和 mem_fun_ref。这些可能会满足您的需求。

    【讨论】:

    • 其实它可能不是一个类的成员。它可能是一个函数,我创建的只是包装器(比如将度数转换为弧度)。
    • @Oxi:“它可能不会”-> 实际上不是?还是你想同时允许?
    猜你喜欢
    • 2018-06-26
    • 2015-06-08
    • 2020-07-28
    • 1970-01-01
    • 2013-01-27
    • 2015-10-22
    • 2014-01-24
    • 2013-06-17
    • 1970-01-01
    相关资源
    最近更新 更多