你能传递一个函数,以便稍后调用它吗?

3
我希望拥有一个只包含一个方法的对象,该方法调用一个函数(但是每个对象应该调用不同的函数)。我会尝试通过示例来说明我的意思:
class Human
{
    public:
        void setMyFunction(void func);  // specify which function to call
        void callMyFunction();  // Call the specified function
};

void Human::setMyFunction(void func)    // ''
{
    myFunction = func;
}

void Human::callMyFunction()    // ''
{
    myFunction();
}

void someRandomFunction()   // A random function
{
    // Some random code
}

int main()
{
    Human Lisa;     // Create Object
    Lisa.setMyFunction();   // Set the function for that object
    Lisa.callMyFunction();  // Call the function specified earlier
}

这段代码显然无法工作,但我希望你能理解我想要实现的目标。

MfG,TPRammus


3
你需要使用 std::function - François Andrieux
你想传递给类的函数签名会是相同的吗?还是它应该接受 int(int, int)double(double)void(int) 等不同的签名呢? - NathanOliver
你也可以使用函数指针。 - Gavin
@FrançoisAndrieux,看起来简单的函数指针就可以了,这比std::function更有效率。 - SergeyA
@SergeyA 或许是这样,但是当处理这种问题时,了解std::function是一个重要的工具,即使它不适合你。 - François Andrieux
2个回答

5
你可以使用 std::function
#include <functional>

class Human
{
    std::function<void()> mFunc;
public:
    void setMyFunction(std::function<void()> func) { mFunc = func; }
    void callMyFunction() { if (mFunc) mFunc(); }
};

Demo


Why std::function? - SergeyA
1
为了通用性并允许捕获lambda。 - Jarod42
非常感谢,这个解决方案有效。我之前尝试过,但是因为没有人告诉我要 #include <functional>(我现在才发现),所以它没有起作用。 - TPRammus
@SergeyA:我认为这可能是过早的优化。但指针确实也是可能的。 - Jarod42
@FrançoisAndrieux,我知道std::function的好处。我也意识到它的缺点。例如,它会导致重载函数的可怕语法。 - SergeyA
显示剩余4条评论

4
我建议使用简单的函数指针。只需这样做:
class Human
{
    public:
        using func_t = void (*)(); 
        void setMyFunction(func_t f) {
             func = f;
        }
        void callMyFunction() {
             func();
        }
     private:
        func_t func;
};

为什么有些人更喜欢使用函数指针而不是std::function的原因如下:

  • 性能。调用std::function通常比通过指针调用函数要慢。
  • 当需要将std::function绑定到重载函数时,其语法非常丑陋。

例如:

void foo();
void foo(int x = 0);

void check() {
  Human h;
  h.setMyFunction(&foo);
}

编译将失败。


5
给一个帖子点个踩是很酷的。但更酷的是解释一下为什么要这样做。 - SergeyA

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接