Функтор (програмування)

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до: навігація, пошук

Фу́нктор (англ. function object), об'єкт-функція — концепція в програмуванні, яка передбачає використання об'єкта класу в якості функції (часто зі збереженням синтаксису виклику).

Використання[ред.ред. код]

Функтори легко використовувати для написання колбеків.

C та C++[ред.ред. код]

Розглянемо приклад функції сортування, яка для порівняння двох елементів використовує колбек-функцію. Програма може мати такий вигляд:

# include <stdlib.h>
 
/* колбек-функція порівняння елементів */
int compare_ints_function(void *A, void *B) {
  return *((int *)(A)) < *((int *)(B));
}/* С декларація функції сортування */
void sort(void *first_item, size_t item_size, void *last_item, int (*cmpfunc)(void *, void *));int main(void) {
    int items[] = {4, 3, 1, 2};
    sort((void *)(items), sizeof(int), (void *)(items + 3), compare_ints_function);
    return 0;
}

У C++ замість функції можна використати об'єкт класу в якому перевизначений оператор operator(). Програма може мати такий вигляд:

struct compare_class {
  bool operator()(int A, int B) const {
    return A < B;
  }
};// С++ декларація функції сортування
template <class ComparisonFunctor>
void sort_ints(int* begin_items, int num_items, ComparisonFunctor c);int main() {
    int items[] = {4, 3, 1, 2};
    sort_ints(items, sizeof(items)/sizeof(items[0]), compare_class());
}

Зауваж, що синтакс передачі колбеку в sort_ints() ідентичний, але в С++ варіанті передається об'єкт а не вказівник на функцію. Під час виклику колбек-функція виконується як і будь-який інший метод і тому має повний доступ до інших методів та полів класу.

C#[ред.ред. код]

У C# функтори реалізовано у вигляді делегатів.

Objective-C[ред.ред. код]

В Objective-C об'єкт-функція створюється шляхом використання класу NSInvocation. Для створення функтора потрібні: сигнатура метода, цільовий об'єкт та вказівник метода (selector). Приклад коду в якому викликається метод buildDocument:

// створення функтора
SEL sel = @selector(buildDocument);
NSInvocation* inv = [NSInvocation invocationWithMethodSignature:
                     [self methodSignatureForSelector:sel]];
[inv setTarget:self];
[inv setSelector:sel];
 
// запустити викликати
[inv invoke];

Перевага класу NSInvocation в тому що цільовий об'єкт можна змінити після створення екземпляру NSInvocation. Один екземпляр NSInvocation можна перевикористати для виклику на різних об'єктах.