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

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

#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);
}

Ответы

Ответ 1

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

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

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

Ответ 2

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

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

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

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

Ответ 6

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