C ++ Как создать функцию, которая принимает в качестве аргумента ссылку на указатель на функцию? - PullRequest
1 голос
/ 13 января 2011

Я использую указатели на функции typedef'd:

typedef int (* ptr2Func) ();

И функция, которая при присвоении числа будет выбирать указатель функции для функции, которая уже объявлена.

ptr2Func getPtr2Func (int function);

Так что, если вы используете getPtr2Func (1); вы получите указатель на первую функцию.

Однако сейчас я хочу сделать совершенно противоположную вещь: передать ссылку на указатель функции в функцию, которая, в свою очередь, вернет номер функции. Т.е. у меня есть 4 тестовые функции, которые ничего не делают, кроме отображения сообщения. if getPtr2Func (1); вызывается указатель на функцию function1.

Могу ли я сделать это: int getFuncNum (ptr2Func * & func);

И, таким образом, получить номер функции, на которую указывает указатель этой функции? Предполагая, что я знаю все функции, которые отображаются на число, указанное в getPtr2Func, я мог бы использовать регистр переключения или несколько if-else, чтобы найти, какой адрес этих функций соответствует указателю функции, переданному в качестве аргумента, нет?

Также, каков будет правильный синтаксис для этого?

Заранее спасибо! :)

Edit:

Не важно, я нашел ответ ...

Просто передать его как есть и сравнить адреса ...

typedef int(*ptr2Func)();

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

Работает с небольшим тестированием, которое я сделал ... (test1 () - это функция ...) Хотя я не знаю, есть ли более эффективный или безопасный способ сделать это ...

Ответы [ 3 ]

1 голос
/ 13 января 2011
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
0 голосов
/ 13 января 2011

Чтобы понять, как работают подобные вещи, лучше взглянуть на то, как построен менеджер обратных вызовов.Обычно, когда вы пишете такую ​​функцию обратного вызова, вы передаете экземпляр и статический адрес метода.Вы захотите создать менеджер обратного вызова, который будет выглядеть примерно так:

...

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, поэтому не ожидайте, что он будет работать с копированием / вставкой.

0 голосов
/ 13 января 2011

Не важно, я нашел ответ ...

Просто передал его как есть и сравнивал адреса ...

typedef int (* ptr2Func) ();

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

Работает с небольшим тестированием, которое я сделал ... (test1 () - это функция ...) Хотя я не знаю, есть ли более эффективный или безопасный способ сделать это ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...