【问题标题】:C++ How to create a function which takes as argument a reference to a function pointer?C ++如何创建一个函数,该函数将函数指针的引用作为参数?
【发布时间】:2011-01-13 19:53:00
【问题描述】:

我正在使用函数指针 typedef'd:

typedef int(*ptr2Func)();

一个函数,当给定一个数字时,它将为一个已经声明的函数选择一个函数指针。

ptr2Func getPtr2Func(int function);

所以如果你使用 getPtr2Func(1);你得到一个指向第一个函数的函数指针。

但是我现在想做完全相反的事情:将函数指针引用传递给函数,该函数又将返回函数的编号。 即:我有 4 个测试功能,除了显示一条消息之外什么都不做。 如果 getPtr2Func(1);被调用,得到一个指向function1的函数指针。

我可以这样做吗: int getFuncNum(ptr2Func*& func);

从而得到这个函数指针指向的函数的编号?假设我知道所有映射到给定 getPtr2Func 的数字的函数,我可以使用 switch case 或多个 if-else 来查找这些函数的哪个地址与作为参数传递的函数指针匹配,不是吗?

另外,这样做的正确语法是什么?

提前致谢! :)

编辑:

没关系,我找到了答案……

按原样传递并比较地址...

typedef int(*ptr2Func)();

int findFunc(ptr2Func func){ if (func == &test1){ return 1; } }

适用于我所做的一些小测试...(test1() 是一个函数...)不知道是否有更有效或更安全的方法来执行此操作...

【问题讨论】:

    标签: c++ function-pointers


    【解决方案1】:
    ptr2Func*& func

    看起来很可怕,函数指针指向函数指针的引用?

    工作代码:

    #include <iostream>
    #include <vector>
    using namespace std;
    
    typedef int(*ptr2Func)();
    
    int zero() { return 10; }
    int one() { return 11; }
    int two() { return 12; }
    int three() { return 13; }
    
    const ptr2Func functions[] = { zero, one, two, three };
    
    //possible other logic
    ptr2Func getPtr2Func(int number) { return functions[number]; }
    
    //possible other logic (std::map, whatever)
    int getPtr2FuncNum(ptr2Func func)
    {
        for (size_t i = 0; i < sizeof(functions) / sizeof(*functions); ++i)
            if (functions[i] == func)
                return i;
        return -1;
    }
    
    int main()
    {
        ptr2Func p = getPtr2Func(2);
        cout << p() << '\n'; //12
        cout << getPtr2FuncNum(p) << '\n'; //2
    
        return 0;
    }
    

    输出:

    12
    2

    【讨论】:

    • 这只是一个指向函数指针的引用,不涉及第二个函数指针。
    【解决方案2】:

    要了解这类东西的工作原理,最好看看回调管理器是如何构建的。通常,当您编写这样的回调函数时,您会传递实例和方法的静态地址。您需要创建一个如下所示的回调管理器:

    ...

    class MyCallbackClass
    {
    
        public:
           typedef void (MyClass::*CallbackFunction)(int arg);
           MyCallbackClass(MyClass * callbackObj, void(CallbackFunction callbackFunction) 
           {
               mCallbackObj = callbackObj;
               mCallbackFunction = callbackFunction;
           };
        private:
           MyClass * mCallbackObj;
           CallbackFunction mCallbackFunction;
    
    };
    

    ...然后在您的主类中添加一个回调函数...

    // The callback -- outputs "3" (see below)
    void MyClass::myFunc(int arg)
    {
        cout << arg << "\n";
    }
    

    ...然后创建回调管理器的实例

    // Implementation
    MyCallbackClass myCallback = new MyCallbackClass(this, &MyClass::myFunc);
    

    ...您的回调管理器现在可以在您传入的实例/方法上调用一个函数...

    // (call this from the instance of MyCallbackClass)
    (mCallbackObj->*mCallbackFunction)(3);
    

    这段代码都是在 stackoverflow 上手写的,所以不要指望它可以与复制/粘贴一起使用。

    【讨论】:

      【解决方案3】:

      没关系,我找到了答案……

      按原样传递并比较地址...

      typedef int(*ptr2Func)();

      int findFunc(ptr2Func func){ if (func == &test1){ 返回 1; } }

      适用于我所做的一些小测试... (test1() 是一个函数...) 不知道是否有更有效或更安全的方法来做到这一点......

      【讨论】:

        猜你喜欢
        • 2011-02-21
        • 1970-01-01
        • 2021-09-08
        • 2022-01-20
        • 2011-07-11
        • 1970-01-01
        • 1970-01-01
        • 2017-11-28
        • 1970-01-01
        相关资源
        最近更新 更多