Почему функции обратного вызова должны быть статическими при объявлении в классе - PullRequest
16 голосов
/ 08 марта 2010

Я пытался объявить функцию обратного вызова в классе, а затем где-то я прочитал, что функция должна быть статической, но это не объясняет почему?

#include <iostream>
using std::cout;
using std::endl;

class Test
{
public:
    Test() {}

    void my_func(void (*f)())
    {
        cout << "In My Function" << endl;
        f(); //Invoke callback function
    }

    static void callback_func()
    {cout << "In Callback function" << endl;}
};

int main()
{
    Test Obj;
    Obj.my_func(Obj.callback_func);
}

Ответы [ 6 ]

20 голосов
/ 08 марта 2010

Функция-член - это функция, для которой требуется вызвать экземпляр класса. Функция членов не может быть вызвана без предоставления экземпляра для вызова. Это иногда затрудняет использование.

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

Посмотрите на std :: function (или std :: tr1 :: function или boost :: function, если ваш компилятор еще не предоставляет), это полезно в вашем случае, так как позволяет вам использовать все, что вызываемый (предоставляющий () синтаксис или оператор) в качестве обратного вызова, включая вызываемые объекты и функции-члены (см. std :: bind или boost :: bind для этого случая).

8 голосов
/ 08 марта 2010

Обратные вызовы должны быть статическими, чтобы они не имели неявного параметра this в качестве первого аргумента в сигнатуре своей функции.

4 голосов
/ 08 марта 2010

Нестатические методы требуют экземпляра this и могут быть вызваны только для экземпляра объекта.

Тем не менее, можно использовать нестатические обратные вызовы, но их синтаксически гораздо сложнее написать. См. http://www.newty.de/fpt/callback.html#member для объяснения.

3 голосов
/ 08 марта 2010

Маршал Клайн дает вам полный ответ здесь , Весь раздел содержит все, что вам нужно знать.

Подводя итог, можно объяснить, что вам нужен статический член, потому что указатель this не нужен (в отличие от обычных методов-членов). Но в нем также говорится, что использование статического может быть недостаточно для всех компиляторов, так как соглашение о вызовах C ++ может быть разным в C и C ++.

Поэтому рекомендуется использовать extern "C" функцию, не являющуюся членом.

3 голосов
/ 08 марта 2010

Он должен быть статическим, чтобы сигнатура функции совпадала. Когда вызывается функция-член, в вызов включается скрытый параметр (т. Е. Указатель this). В статических функциях-членах этот указатель не передается в качестве параметра.

0 голосов
/ 08 марта 2010

Если вы используете указатели на функции, среда выполнения не может передать ссылку на экземпляр при вызове функции. Но вы можете использовать std :: mem_fun <>, чтобы использовать функторы и методы-члены.

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