Арифметичні оператори зазвичай використовуються для арифметичних операцій. Чи не приємно мати +, об'єднайте два рядки? Увімкнення того, що, як кажуть, перевантажує оператор арифметичного додавання для рядків.
Оператор приросту ++ додає 1 до int або float. При роботі з покажчиками він не додає 1 до покажчика. Це вказує вказівник на наступний послідовний об’єкт у пам’яті. Ітератор вказує на наступний об'єкт у пов'язаному списку, але об'єкти пов'язаного списку знаходяться в різних місцях пам'яті (не в послідовних регіонах). Чи не було б непогано перевантажити оператор збільшення для ітератора, щоб збільшити, але вказати на наступний елемент у списку зв’язаних?
У цій статті пояснюється перевантаження в C++. Він розділений на дві частини: перевантаження функції та перевантаження оператора. Маючи вже базові знання на C ++, необхідно зрозуміти решту статті.
Зміст статті
- Перевантаження функції
- Перевантаження оператора
- Приклад перевантаження оператора класу рядків
- Перевантаження оператора ітератора
- Висновок
Перевантаження функції
Наступна функція додає два ints і повертає int:
int add (int no1, int no2)int сума = no1 + no2;
сума повернення;
Прототипом цієї функції є:
int add (int no1, int no2);
Прототип функції в заголовку функції, що закінчується крапкою з комою. Наступна функція з тим самим іменем, але з іншим прототипом, додала б три поплавці і повернула б поплавок:
float add (float no1, float no2, float no3)
плаваюча сума = no1 + no2 + no3;
сума повернення;
Як компілятор розрізняє, яку функцію викликати, оскільки дві або більше функцій мають однакову назву? Компілятор використовує кількість аргументів і типів аргументів, щоб визначити, яку функцію викликати. Список параметрів перевантажених функцій повинен відрізнятися за їх кількістю та / або типами параметрів. Отже, виклик функції,
int sm = додати (2, 3);буде викликати цілочисельну функцію, тоді як функція викличе,
float sme = додати (2.3, 3.4, 2.0);викликав би функцію float. Примітка: бувають ситуації, коли компілятор відхилить перевантажену функцію, коли кількість аргументів однакова, але різного типу! - Причина: - дивіться пізніше.
Наступна програма вводить у дію зазначені вище сегменти коду:
#включативикористання простору імен std;
int add (int no1, int no2)
int сума = no1 + no2;
сума повернення;
float add (float no1, float no2, float no3)
плаваюча сума = no1 + no2 + no3;
сума повернення;
int main ()
int sm = додати (2, 3);
кут<
кут<
Результат:
5
7.7
Перевантаження оператора
Арифметичні оператори використовуються для перевантаження операцій у типах класів. Ітератор - це тип класу. Оператори збільшення та зменшення використовуються для перевантаження операцій для ітератора.
Приклад перевантаження оператора класу рядків
У цьому розділі наведено приклад, коли + перевантажується для просто розробленого класу рядків, який називається пружинним класом. + об'єднує літерали двох рядкових об'єктів, повертаючи новий об'єкт із об'єднаними літералами. Об’єднання двох літералів означає приєднання другого літералу до кінця першого літералу.
Тепер C ++ має спеціальну функцію-член для всіх класів, яка називається оператором. Програміст може використовувати цю спеціальну функцію для перевантаження операторів, таких як +. Наступна програма показує перевантаження оператора + для двох рядків.
#включативикористання простору імен std;
клас весна
публічний:
// члени даних
char val [100];
int n;
char concat [100];
// функції члена
пружина (char arr [])
для (int i = 0; i<100; ++i)
val [i] = arr [i];
якщо (arr [i] == '\ 0')
перерва;
int i;
для (i = 0; i<100; ++i) if (arr[i] == '\0') break;
n = i;
оператор пружини + (spring & st)
int newLen = n + st.n;
char newStr [newLen + 1];
для (int i = 0; i
весна obj (newStr);
return obj;
;
int main ()
char ch1 [] = "Я тебе ненавиджу! "; пружина str1 (ch1);
char ch2 [] = "Але вона любить тебе!"; пружина str2 (ch2);
char ch3 [] = "один"; пружина str3 (ch3);
str3 = str1 + str2;
кут<
Значення str1: "Я тебе ненавиджу! ". Значення str2: "Але вона любить тебе!". Значення str3, яке є, str1 + str2, є результатом:
"Я тебе ненавиджу! Але вона любить тебе!"
що є об’єднанням двох рядкових літералів. Самі рядки є екземплярами об'єктів.
Визначення функції оператора знаходиться всередині опису (визначення) класу рядків. Починається з типу повернення, "spring" для "string". Спеціальна назва "оператор, слідуй за цим". Після цього є символ оператора (який потрібно перевантажити). Тоді є список параметрів, який насправді є списком операндів. + є двійковим оператором: це означає, що він бере лівий і правий операнд. Однак, згідно специфікації C ++, список параметрів тут має лише правильний параметр. Тоді є тіло операторської функції, що імітує звичайну поведінку оператора.
За специфікацією C ++, визначення оператора + приймає лише правий параметр операнда, оскільки решта опису класу є параметром лівого операнда.
У наведеному вище коді лише визначення функції + () стосується + перевантаження. Решта коду для класу - це звичайне кодування. Усередині цього визначення два рядкові літерали об'єднані в масив, newStr []. Після цього фактично створюється (створюється екземпляр) новий об’єкт рядка, використовуючи аргумент, newStr []. В кінці визначення оператора + () функції повертається новостворений об'єкт, що має об'єднаний рядок.
У функції main () додавання здійснюється за допомогою оператора:
str3 = str1 + str2;Де str1, str2 та str3 - це рядкові об'єкти, які вже створені у main (). Вираз "str1 + str2" з його + викликає функцію-член оператора + () в об'єкті str1. Функція-член оператора + () в об'єкті str1 використовує str2 як свій аргумент і повертає новий об'єкт із (розробленим) об'єднаним рядком. Оператор присвоєння (=) повного оператора замінює вміст (значення змінних) об'єкта str3 на вміст поверненого об'єкта. У функції main () після додавання значення члена даних str3.val більше не "один"; це об'єднаний (доданий) рядок, "Я ненавиджу тебе! Але вона любить тебе!". Функція-член оператора + () в об'єкті str1 використовує рядковий літерал власного об'єкта та рядковий літерал свого аргументу str2, щоб створити об'єднаний рядковий літерал.
Перевантаження оператора ітератора
При роботі з ітератором береться щонайменше два об'єкти: пов'язаний список і сам ітератор. Насправді беруть участь принаймні два класи: клас, з якого створюється екземпляр пов'язаного списку, і клас, з якого створюється екземпляр ітератора.
Зв’язаний список
Діаграма для об’єкта подвійного зв’язку:
Цей список має три елементи, але може бути й більше. Три елементи тут є елементами цілих чисел. Перший має значення 14; наступний має значення, 88; і останній має значення 47. Кожен елемент тут складається з трьох послідовних місць.
Це на відміну від масиву, де кожен елемент є одним розташуванням, а всі елементи масиву знаходяться в послідовних розташуваннях. Тут різні елементи знаходяться в різних місцях серії пам’яті, але кожен елемент складається з трьох послідовних розташувань.
Для кожного елемента середнє розташування містить значення. Правильне розташування має вказівник на наступний елемент. Ліве розташування має вказівник на попередній елемент. Для останнього елемента правильне розташування вказує на теоретичний кінець списку. Для першого елемента ліве розташування вказує на теоретичний початок списку.
За допомогою масиву оператор збільшення (++) збільшує покажчик, щоб вказувати на фізично наступне розташування. У списку елементи не знаходяться в послідовних областях пам'яті. Отже, оператор приросту може бути перевантажений, перемістіть ітератор (покажчик) від одного елемента до логічно наступного елемента. Те саме прогнозування стосується оператора зменшення (-).
Прямий ітератор - це ітератор, який при залученні вказує на наступний елемент. Зворотний ітератор - це ітератор, який при залученні вказує на попередній елемент.
Перевантаження ++ оголошення -
Перевантаження цих операторів здійснюється в описі класу (визначенні) ітератора.
Синтаксис прототипу перевантаження оператора приросту, префікса, є
Оператор ReturnType ++ ();Синтаксис прототипу перевантаження оператора приросту, постфікс, є
Оператор ReturnType ++ (int);Синтаксис прототипу перевантаження оператора декременту, префікса, є
Оператор ReturnType - ();Синтаксис прототипу перевантаження оператора приросту, постфікс, є
Оператор ReturnType - (int);Висновок
Перевантаження означає надання іншого значення функції або оператору. Функції перевантажені в одному і тому ж обсязі. Що відрізняє перевантажені функції, це кількість та / або типи параметрів у їх списках параметрів. У деяких випадках, коли кількість параметрів однакова, але з різними типами, компілятор відхиляє перевантаження - див. Пізніше. Багато звичайні оператори можуть бути перевантажені в класи, з яких створюються екземпляри об'єктів. Це робиться шляхом надання типу повернення, списку параметрів і тіла спеціальній функції з іменем operator в описі класу.