Студопедия
Новини освіти і науки:
МАРК РЕГНЕРУС ДОСЛІДЖЕННЯ: Наскільки відрізняються діти, які виросли в одностатевих союзах


РЕЗОЛЮЦІЯ: Громадського обговорення навчальної програми статевого виховання


ЧОМУ ФОНД ОЛЕНИ ПІНЧУК І МОЗ УКРАЇНИ ПРОПАГУЮТЬ "СЕКСУАЛЬНІ УРОКИ"


ЕКЗИСТЕНЦІЙНО-ПСИХОЛОГІЧНІ ОСНОВИ ПОРУШЕННЯ СТАТЕВОЇ ІДЕНТИЧНОСТІ ПІДЛІТКІВ


Батьківський, громадянський рух в Україні закликає МОН зупинити тотальну сексуалізацію дітей і підлітків


Відкрите звернення Міністру освіти й науки України - Гриневич Лілії Михайлівні


Представництво українського жіноцтва в ООН: низький рівень культури спілкування в соціальних мережах


Гендерна антидискримінаційна експертиза може зробити нас моральними рабами


ЛІВИЙ МАРКСИЗМ У НОВИХ ПІДРУЧНИКАХ ДЛЯ ШКОЛЯРІВ


ВІДКРИТА ЗАЯВА на підтримку позиції Ганни Турчинової та права кожної людини на свободу думки, світогляду та вираження поглядів



Об’єкти-функції

Функція accumulate, розглянута у попередньому пункті, є дуже загальною з погляду використання ітераторів, але вона є недостатньо загальною щодо прийнятих у ній припущень про типи значень, на які посилаються ітератори (вони називаються типами значень ітераторів). У визначенні функції accumulate використовуються вирази

init = init + *first++;

за припущення, що в типі значень визначена операція +. Тому ця функція може використовуватися для вбудованих числових типів мови С++, а також для довільного типу Т, визначеного користувачем, в якому визначена операція +, щоб додавати значення елемен­тів послідовності. Але абстрактний зміст нагромадження (accumula­te) застосовується не лише до підсумовування. Можна, наприклад, нагромаджувати добуток значення елементів послідовності. Тому STL пропонує іншу, загальнішу версію функції accumulate:

template <class InputIterator, class T, class BinaryOperation>;

T accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op)

{

while (first != last)

init = binary_op(init,*first++);

return init;

}

У цьому визначенні вводиться ще один параметр, binary_op, який використовується замість + та визначає бінарну операцію, застосовувану для об’єднання значень. Застосовування нової версії функції accumulate ілюструється таким прикладом:

#include <vector.h>

#include <algo.h>

#include <assert.h>

int mult(int x, int y){return x*y;}

int main()

{

cout<< «Використання параметричної функції accumulate» <<«для обчислення добутку»<< end1;

int x[5] = {2,3,5,7,11};

//ініціалізація вектора vector1 значенням від x[0] до x[4]

vector<int> vector1(x,x+5);

int product = accumulate(vector1.begin(),vector1.end(),1,mult);

assert(product == 2310);

}

(Зауважимо, що у програмі початкове значення (init) замінено з 0 на 1). Тут як accumulate використовується звичайна функція, але в мові С++ підтримується й інша можливість: передача об’єкта-функції; об’єктом-функцією у STL називається об’єкт, тип якого визначено як клас (або структура), членом якого є операція виклику функції operator( ). У наведеному далі прикладі показана найпростіша форма об’єкта-функції:

#include <vector.h>

#include <algo.h>

#include <assert.h>

class multiply{

public:

int operator()(int x, int y)const{return x*y;}

};

int main()

{

cout<< «Використання параметричної функції accumulate» <<«для обчислення добутку»<< end1;

int x [5] = {2,3,5,7,11};

//ініціалізація вектора vector1 значенням від x[0] до x[4]

vector<int> vector1(x,x+5);

int product = accumulate(vector1.begin(), vector1.end(), 1, multiply());

assert (product == 2310);

}

Визначення операції виклику функції operator( ) в класі multiply породжує об’єкт, який може бути застосований у списку параметрів точно так, як і функція. Зазначимо, що об’єкт, переданий як третій параметр функції accumulate, утворюється за допомогою (неявного) конструктора multiply( ) класу multiply. Зауважимо також, що цей об’єкт не має зв’язаної з ним пам’яті аналогічно визначенню функції.

У чому ж полягає перевага об’єктів-функцій над звичайними функціями? На відміну від звичайних функцій об’єктам-функціям може бути повідомлена додаткова інформація, яка може бути використана параметричними алгоритмами чи контейнерами, коли їм знадобиться складніша інформація про властивості функції. Крім того, виклики об’єктів-функцій звичайно змінюються компілятором С++ на прямі текстуальні вставки, що забезпечує велику ефективність у їх використанні (економиться час на виклик функції).

Зауважимо також, що у прикладі можна було б не визначати клас multiply, оскільки у STL існує таке визначення, щоправда, у загальнішій формі:

template<class T>

class times: public binary_function<T,T,T>{

public:

T operator()(const T& x, const T& y) const{

return x*y;

}

};

Цей клас наслідує другому компоненту STL класу binary_func­tion, мета введення якого — забезпечити сховище додатковою інформацією про функції. Використовуючи це визначення, можна переписати попередній приклад так:

#include <vector.h>

#include <algo.h>

#include <assert.h>

int main()

{

cout<< «Використання параметричної функції accumulate» <<«для обчислення добутку»<< end1;

int x[5] = {2,3,5,7,11};

//ініціалізація вектора vector1 значенням від x[0] до x[4]

vector<int> vector1(x,x+5);

int product = accumulate(vector1.begin(), vector1.end(), 1, times<int>());

assert(product = = 2310);

}

Клас times визначено у файлі-заголовку function.h, який вже вставлено у програму у складі algo.h. times<int>( ), що є звертанням до (неявного) конструктора класу times з типом int.




Переглядів: 421

<== попередня сторінка | наступна сторінка ==>
Ітератори | Адаптери

Не знайшли потрібну інформацію? Скористайтесь пошуком google:

  

© studopedia.com.ua При використанні або копіюванні матеріалів пряме посилання на сайт обов'язкове.


Генерація сторінки за: 0.014 сек.