Я объясню на примерах C ++, потому что это язык, где эта проблема присутствует (и решена другим способом).
Простой указатель функции просто содержит адрес функции, ничего больше.
Рассмотрим функцию
void f(int x) { return; }
Теперь простой указатель функции объявляется и присваивается следующим образом:this:
void (*fptr)(int) = &f;
И вы можете использовать это просто:
foo(5); // calls f(5)
Однако в объектно-ориентированном языке мы обычно имеем дело с функциями-членами, а не со свободными функциями.И вот тут все становится неприятно.Рассмотрим следующий класс:
class C { void g(int x) { return; } };
Объявление указателя функции на C :: g выполняется следующим образом:
void (*C::gptr)(int) = &C::g;
Причина, по которой нам нужен другой синтаксис, заключается в том, что функции-члены имеютскрытый параметр this
, поэтому их сигнатура отличается.
По той же причине вызывать их проблематично.Этот параметр this
нуждается в значении, что означает, что вам нужен экземпляр.Вызов указателя на функцию-член выполняется следующим образом:
C c;
(c.*gptr)(5); // calls c.g(5);
Помимо странного синтаксиса, реальная проблема заключается в том, что вам нужно передать объект вместе с указателем на функцию, когда вы действительно просто хотитеобойти одну вещь.
Очевидная идея состоит в том, чтобы заключить в капсулу два, и это то, что делегат.Вот почему делегат считается более ООП.Я понятия не имею, почему он считается более безопасным для типов (возможно, потому что вы можете привести указатели функций к void *).
Кстати, решение C ++ в C ++ 0x взято из Boost.Он называется std::function
и std::bind
и работает так:
std::function<void (C*, int)> d = std::bind(&c::g, &c);
d(5); // calls c.g(5);