Я пытался объявить функцию обратного вызова в классе, и затем где-нибудь я читал, функция должна быть статичной, но Это не объяснило почему?
#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);
}
Функция-член - это функция, для которой требуется вызов экземпляра класса. Функция-член не может быть вызвана без предоставления экземпляра для вызова. Иногда это затрудняет использование.
Статическая функция почти похожа на глобальную функцию: для ее вызова не требуется экземпляр класса. Таким образом, вам нужно только получить указатель на функцию, чтобы иметь возможность ее вызвать.
Взгляните на std :: function (или std :: tr1 :: function или boost :: function, если ваш компилятор еще не предоставляет его), это полезно в вашем случае, поскольку позволяет вам использовать все, что callable (обеспечивающий () синтаксис или оператор) в качестве обратного вызова, включая вызываемые объекты и функции-члены (см. std :: bind или boost :: bind для этого случая).
Она должна быть статической, чтобы сигнатура функции совпадала. Когда вызывается функция-член, в вызов включается скрытый параметр (т.е. указатель "this"). В статических функциях-членах указатель this не передается в качестве параметра.
Нестатические методы требуют наличия экземпляра 'this' и могут быть вызваны только для экземпляра объекта.
Однако можно использовать нестатические обратные вызовы, но их синтаксически гораздо сложнее написать. См. http://www.newty.de/fpt/callback.html#member для объяснения.
Маршал Клайн дает полный ответ здесь. . Весь раздел содержит все, что вам нужно знать.
Вкратце он объясняет, что вам нужен статический член, потому что указатель this
не нужен (в отличие от обычных методов-членов). Но здесь также говорится о том, что использование static может быть недостаточно для всех компиляторов, так как соглашение о вызове C++ может отличаться между C и C++.
Поэтому рекомендуется использовать extern "C"
нечленную функцию.
Если вы используете указатели функций, среда выполнения не может передать ссылку на экземпляр при вызове функции. Но вы можете использовать std::mem_fun<>, в для использования функторов и методов-членов.
Обратные вызовы должны быть статическими, чтобы у них не было неявного параметра this
в качестве первого аргумента в их сигнатуре функции.