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

Фу́нкціональний об'єкт (англ. 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 можна перевикористати для виклику на різних об'єктах.

This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.