Урок №147. Перевантаження оператора ()

  Юрій  | 

  Оновл. 25 Вер 2021  | 

 143

На цьому уроці ми розглянемо перевантаження оператора () в мові С++.

Перевантаження оператора ()

Всі оператори, перевантаження яких ми розглядали дотепер, дозволяли нам самостійно визначати тип параметрів в функції перевантаження оператора, але не їх кількість. Наприклад, оператор == завжди приймає два параметри, тоді як оператор ! завжди приймає один параметр. Оператор () є особливо цікавим, оскільки дозволяє змінювати як тип параметрів, так і їх кількість.

Але слід пам’ятати про дві речі:

   По-перше, перевантаження круглих дужок повинне здійснюватися через метод класу.

   По-друге, в не об’єктно-орієнтованому С++ оператор () є оператором виклику функції. У випадку з класами перевантаження круглих дужок виконується в методі operator()(){} (в оголошенні функції перевантаження знаходяться дві пари круглих дужок).

Розглянемо наступний клас:

Матриці є ключовою концепцією в лінійній алгебрі та часто використовуються в геометричному моделюванні і в 3D-графіці. Все, що вам потрібно зараз знати — це те, що клас Matrix є двовимірним масивом (5×5 типу double).

На уроці про перевантаження оператора індексації ми використовували оператор [] для прямого доступу до елементів закритого одновимірного масиву. Тут же нам потрібен доступ до елементів двовимірного масиву. Оскільки оператор [] обмежений лише одним параметром, то його функціональності недостатньо для доступу до двовимірного масиву.

Однак, оскільки оператор () може приймати різну кількість параметрів, ми можемо оголосити версію operator(), яка прийматиме два цілочисельних параметри (два індекси), і використовуватиме ці індекси для доступу до елементів нашого двовимірного масиву. Наприклад:

Результат виконання програми:

3.6

Виконаємо перевантаження оператора () ще раз, але вже без використання будь-яких параметрів:

Результат виконання програми:

0

Оскільки оператор () є дуже гнучким, то може виникнути спокуса використати його для самих різних цілей. Однак це не рекомендується робити, оскільки оператор () є не дуже інформативним і часто може бути не зрозуміло, що він робить. У прикладі, наведеному вище, функцію очищення масиву краще було б записати у вигляді методу clear() або erase(), оскільки matrix.erase() виглядає набагато інформативніше, ніж matrix().

Функтори в C++

Перевантаження оператора () використовується в реалізації функторів (або “функціональних об’єктів”) — класи, які працюють як функції. Перевага функтора над звичайною функцією полягає в тому, що функтори можуть зберігати дані в змінних-членах (оскільки вони самі є класами). Ось приклад використання простого функтора:

Зверніть увагу, використання класу Accumulator виглядає так само, як і виклик звичайної функції, але наш об’єкт класу Accumulator може зберігати значення, яке збільшується.

Ви можете запитати: “Навіщо використовувати клас, якщо все можна реалізувати і через звичайну функцію зі статичною локальною змінною?”. Можна зробити і через static, але, оскільки функції представлені тільки одним глобальним екземпляром (тобто не можна створити кілька об’єктів функції), використовувати цю функцію ми можемо тільки для виконання чогось одного за раз. За допомогою функторів ми можемо створити будь-яку кількість окремих функціональних об’єктів, які нам потрібні, і використовувати їх одночасно.

Висновки

Перевантаження оператора () з двома параметрами використовується для отримання доступу до двовимірних масивів або для повернення підмножин одновимірного масиву (два параметри конкретизуватимуть умови відбору елементів підмножини). Все інше краще реалізувати через окремі методи з більш інформативними назвами, ніж через перевантаження оператора ().

Перевантаження оператора () також часто використовується при створенні функторів. Хоча функтори, які ми використовували вище, є досить простими і зрозумілими, але зазвичай вони використовуються в більш просунутих/складних темах програмування і заслуговують окремого уроку.

Тест

Напишіть клас, змінною-членом якого є рядок. Виконайте перевантаження оператора () для повернення підрядка, який починається з індексу, вказаного в значенні першого параметру. Другий параметр повинен вказувати необхідну довжину підрядка.

Підказки:

   Ви можете використати індекс масиву [] для доступу до окремих символів рядка.

   Ви можете використати оператор += для додавання чого-небудь до рядка.

Наступний фрагмент коду:

Повинен видавати наступний результат:

world!

Відповідь

Оцінити статтю:

1 Зірка2 Зірки3 Зірки4 Зірки5 Зірок (6 оцінок, середня: 5,00 з 5)
Loading...

Залишити відповідь

Ваш E-mail не буде опублікований. Обов'язкові поля відмічені *