Перевантаження скорочених операторів присвоювання +=, -=, *=, /=, %=. Приклади
Дана тема базується на вивченні попередніх тем
- Перевантаження операторів у C++. Операторна функція. Ключове слово operator. Перевантаження арифметичних операторів +, –, *, /. Приклади реалізації вбудованих операторних функцій
- “Дружні” операторні функції: відмінності, реалізація особливості застосування. Перевантаженняоператорів +, –, *, / з допомогою “дружніх” операторних функцій
Зміст
- 1. Особливості перевантаження скорочених операторів присвоювання +=, -=, *=, /=, %=. Загальна форма операторної функції
- 2. Приклад, що демонструє перевантаження оператора += для класу Integer, який реалізує ціле число. Операторна функція оголошується всередині класу
- 3. Приклад, що демонструє перевантаження оператора %= для класу Integer, який реалізує ціле число. Операторна функція оголошується як “дружня” до класу Integer
- 4. Приклад, що демонструє перевантаження оператора *= для класу Complex, який реалізує комплексне число. Операторна функція реалізована всередині класу
- 5. Приклад, що демонструє перевантаження оператора *= для класу Complex, який реалізує комплексне число. Операторна функція реалізована як “дружня” до класу
- 6. Приклад, що демонструє перевантаження оператора /= для масиву чисел типу double. Масив має фіксований розмір. Операторна функція реалізована всередині класу
- 7. Приклад, що демонструє перевантаження оператора /= для масиву чисел типу double. Масив має фіксований розмір. Операторна функція реалізована як “дружня” до класу
- 8. Приклад, що демонструє декілька варіантів перевантаження оператора += для класу Point. Операторна функція operator+=() є перевантаженою і реалізована всередині класу
- Зв’язані теми
Пошук на інших ресурсах:
1. Особливості перевантаження скорочених операторів присвоювання +=, -=, *=, /=, %=. Загальна форма операторної функції
Скорочені оператори присвоювання +=, -=, *=, /=, %= є бінарними, тобто вони вимагають двох операндів.
Якщо операторна функція реалізована в класі, то вона отримує один операнд і має наступну загальну форму
class ClassName { // ... // операторна функція, яка перевантажує один зі скорочених операторів присвоювання ClassName operator##(ClassName obj) { // ... } }
де
- ClassName – ім’я класу, для якого реалізується операторна функція operator##();
- operator##() – деяка операторна функція. Символи ## замінюються символами +=, -=, *=, /=, %=, тобто, операторна функція буде мати відповідно такі імена: operator+=(), operator-=(), operator*=(), operator/=(), operator%=().
- obj – екземпляр (об’єкт) класу ClassName.
Якщо операторна функція реалізована як “дружня”, то вона отримує два операнди. У цьому випадку загальна форма використання операторної функції має вигляд:
class ClassName { // ... // "дружня" операторна функція, // яка перевантажує один зі скорочених операторів присвоювання friend ClassName operator##(ClassName& obj1, ClassName& obj2) { // ... } } // реалізація "дружньої" до класу ClassName операторної функції ClassName operator##(ClassName& obj1, ClassName& obj2) { // ... }
тут obj1, obj2 – посилання на екземпляри класу ClassName, які передаються в “дружню” операторну функцію operator##().
⇑
2. Приклад, що демонструє перевантаження оператора += для класу Integer, який реалізує ціле число. Операторна функція оголошується всередині класу
Задано клас Integer, який реалізує операції над цілочисельним значенням. У класі оголошуються:
- внутрішня змінна number цілого типу, яка зберігає значення;
- два конструктори;
- методи доступу до цілочисельної змінної number;
- операторна функція operator+=(), яка перевантажує скорочений оператор присвоювання +=.
Реалізація класу Integer
// клас Integer - реалізує ціле число class Integer { private: int number; public: // конструктори класу Integer() { number = 0; } Integer(int _number) { number = _number; } // методи доступу int Get(void) { return number; } void Set(int _number) { number = _number; } // перевантаження оператора +=, операторна функція всередині класу Integer operator+=(Integer obj) { number = number + obj.number; // доступ за посиланням return *this; } };
Використання екземпляру (об’єкту) класу Integer в іншому програмному коді може бути, наприклад, таким:
// перевантаження скорочених операторів присвоюванн +=, -= і т.д. Integer d1(10), d2(18); // екземпляри класу Integer int t; // виклик операторної функції operator+=() d1+=d2; // d1.number = d1.number + d2.number t = d1.Get(); // t = 28
За даним зразком можна перевантажувати інші скорочені оператори присвоювання -=, *=, /=, %=.
⇑
3. Приклад, що демонструє перевантаження оператора %= для класу Integer, який реалізує ціле число. Операторна функція оголошується як “дружня” до класу Integer
У класі Integer оголошується “дружня” (friend) операторна функція operator%=(), яка визначає об’єкт класу Integer, який є остачею від ділення об’єктів, що є параметрами функції.
// клас Integer, що реалізує ціле число class Integer { private: int number; public: // конструктори класу Integer() { number = 0; } Integer(int _number) { number = _number; } // методи доступу int Get(void) { return number; } void Set(int _number) { number = _number; } // оголошення "дружньої" до класу Integer операторної функції // яка перевантажує оператор %= friend Integer operator%=(Integer& obj1, Integer& obj2); }; // "дружня" операторна функція до класу Integer // в операторну функцію передаються посилання на клас Integer Integer operator%=(Integer& obj1, Integer& obj2) { obj1.number = obj1.number % obj2.number; // доступ за посиланням return obj1; }
Використання операторної функції operator%=() може бути таким
// перевантаження скорочених операторів присвоюванн +=, -= і т.д. Integer d1(14), d2(6); // екземпляри класу Integer int t; // виклик "дружньої" операторної функції operator%=() d1 %= d2; // d.number = d1.number + d2.number t = d1.Get(); // t = 2 Integer d3(9), d4(5); d3 %= d4; t = d3.Get(); // t = 4
⇑
4. Приклад, що демонструє перевантаження оператора *= для класу Complex, який реалізує комплексне число. Операторна функція реалізована всередині класу
У класі Complex реалізується операторна функція, яка перевантажеує оператор *=. Ця функція реалізує множення комплексних чисел за формулою:
(a+bj)*(c+dj) = (a*c-b*d) + (a*d+b*c)j
Реалізація класу Complex
class Complex { private: double real; // дійсна частина double imag; // уявна частина public: // конструктор класу Complex(double _real, double _imag) { real = _real; imag = _imag; } // методи доступу double GetReal(void) { return real; } double GetImag(void) { return imag; } void Set(double _real, double _imag) { real = _real; imag = _imag; } // операторна функція, яка перевантажує оператор *= // функція реалізує множення комплексних чисел Complex operator*=(Complex obj) { double r; double i; r = real*obj.real - imag*obj.imag; i = real*obj.imag + obj.real*imag; real = r; imag = i; return *this; } };
Демонстрація використання операторної функції
// перевантаження скороченого оператора *= Complex c1(2,3); // 2+3j Complex c2(-1,1); // -1+j double t; // виклик операторної функції *= c1 *= c2; // c1 = -5-1j t = c1.GetReal(); // t = -5 t = c1.GetImag(); // t = -1
⇑
5. Приклад, що демонструє перевантаження оператора *= для класу Complex, який реалізує комплексне число. Операторна функція реалізована як “дружня” до класу
У прикладі реалізується операція множення комплексних чисел з допомогою “дружньої” (friend) операторної функції operator*=(). “Дружня” операторна функція отримує 2 параметри.
class Complex { private: double real; // дійсна частина double imag; // уявна частина public: // конструктор класу Complex(double _real, double _imag) { real = _real; imag = _imag; } // методи доступу double GetReal(void) { return real; } double GetImag(void) { return imag; } void Set(double _real, double _imag) { real = _real; imag = _imag; } // оголошення "дружньої" функції friend Complex operator*=(Complex& c1, Complex& c2); }; // реалізація "дружньої" до класу Complex функції Complex operator*=(Complex& c1, Complex& c2) { double r; double i; r = c1.real * c2.real - c1.imag * c2.imag; i = c1.real * c2.imag + c1.imag * c2.real; c1.real = r; c1.imag = i; return c1; }
Використання класу Complex в іншому методі може бути таким:
// перевантаження скороченого оператора *= Complex c1(3,-2); // 3-2j Complex c2(1,-1); // 1-j double t; // виклик операторної функції *= c1 *= c2; t = c1.GetReal(); // t = -1 t = c1.GetImag(); // t = -5
⇑
6. Приклад, що демонструє перевантаження оператора /= для масиву чисел типу double. Масив має фіксований розмір. Операторна функція реалізована всередині класу
У класі ArrayDouble реалізується масив чисел типу double. Операторна функція operator/=() реалізує поелементне ділення двох масивів
// фіксований масив типу double class ArrayDouble { private: double D[10]; // масив public: // конструктор ArrayDouble() { for (int i=0; i<10; i++) D[i] = 0; } // методи доступу double Get(int index) { if ((index>=0)&&(index<10)) return D[index]; return 0.0; } void Set(int index, double value) { if ((index>=0)&&(index<10)) D[index] = value; } // операторна функція, поелементно ділить два масиви ArrayDouble operator/=(ArrayDouble AD) { // поелементне ділення поточного масиву на масив AD for (int i=0; i<10; i++) D[i] = D[i] / AD.Get(i); return *this; } };
Використання класу ArrayDoble може бути таким
// перевантаження скороченого оператора *= ArrayDouble A1; ArrayDouble A2; double t; // формування масивів for (int i=0; i<10; i++) A1.Set(i,10); // A1 = {10,10,10,10,10,10,10,10,10,10} for (int i=0; i<10; i++) // A2 = {1,2,3,4,5,6,7,8,9,10} A2.Set(i, i+1); // виклик операторної функції A1 /= A2; // перевірка t = A1.Get(0); // t = 10/1 = 10.0 t = A1.Get(1); // t = 10/2 = 5.0 t = A1.Get(2); // t = 10/3 = 3.33333333 t = A1.Get(7); // t = 10/8 = 1.25
⇑
7. Приклад, що демонструє перевантаження оператора /= для масиву чисел типу double. Масив має фіксований розмір. Операторна функція реалізована як “дружня” до класу
У класі ArrayDouble оголошується “дружня” операторна функція, яка реалізує поелементне ділення масивів. Оголошення класу ArrayDouble та операторної функції наступне
// фіксований масив типу double class ArrayDouble { private: double D[10]; // масив public: // конструктор ArrayDouble() { for (int i=0; i<10; i++) D[i] = 0; } // методи доступу double Get(int index) { if ((index>=0)&&(index<10)) return D[index]; return 0.0; } void Set(int index, double value) { if ((index>=0)&&(index<10)) D[index] = value; } // оголошення "дружньої" операторної функції friend ArrayDouble operator/=(ArrayDouble& AD1, ArrayDouble& AD2); }; // реалізація "дружньої" до класу ArrayDouble операторної функції ArrayDouble operator/=(ArrayDouble& AD1, ArrayDouble& AD2) { for (int i=0; i<10; i++) AD1.D[i] = AD1.D[i] / AD2.D[i]; return AD1; }
Використання класу в іншому програмному коді
// перевантаження скороченого оператора *= ArrayDouble A1; ArrayDouble A2; double t; // формування масивів for (int i=0; i<10; i++) A1.Set(i,10); // A1 = {10,10,10,10,10,10,10,10,10,10} for (int i=0; i<10; i++) // A2 = {1,2,3,4,5,6,7,8,9,10} A2.Set(i, i+1); // виклик "дружньої" операторної функції A1 /= A2; // перевірка t = A1.Get(0); // t = 10/1 = 10.0 t = A1.Get(1); // t = 10/2 = 5.0 t = A1.Get(2); // t = 10/3 = 3.33333333 t = A1.Get(7); // t = 10/8 = 1.25
⇑
8. Приклад, що демонструє декілька варіантів перевантаження оператора += для класу Point. Операторна функція operator+=() є перевантаженою і реалізована всередині класу
Операторні функції в класі можуть бути перевантажені. Такі функції мають містити однакову кількість параметрів, але ці параметри мають мати різні типи.
// Клас, що реалізує точку на координатній площині // клас містить дві перевантажені операторні функції operator+=() class Point { private: int x, y; // координати точки public: // конструктори класу Point() { x = y = 0; } Point(int nx, int ny) { x = nx; y = ny; } // методи доступу до членів класу int GetX(void) { return x; } int GetY(void) { return y; } void SetX(int nx) { x = nx; } void SetY(int ny) { y = ny; } // операторна функція '+=' // яка додає 2 точки Point operator+=(Point pt) { x = x + pt.x; y = y + pt.y; return *this; } // операторна функція '+=' // яка збільшує x та y на величину вхідного параметра d Point operator+=(int d) { x = x + d; y = y + d; return *this; } };
У вищенаведеному коді реалізовано дві операторні функції operator+=(), які перевантажують оператор +=.
// операторна функція '+=' // яка додає 2 точки Point operator+=(Point pt) { // ... } // операторна функція '+=' // яка збільшує x та y на величину вхідного параметра d Point operator+=(int d) { // ... }
Нижче продемонстровано використання операторних функцій класу Point.
// перевантаження скороченого оператора += Point p1(2,3); Point p2(4,5); int x, y; // виклик операторної функції додавання екземплярів типу Point p1 += p2; // перевірка x = p1.GetX(); // x = 2+4 = 6 y = p1.GetY(); // y = 3+5 = 8 p2 += p1; x = p2.GetX(); // x = 6+4 = 10 y = p2.GetY(); // y = 8+5 = 13 // виклик операторної функції додавання Point + int p1 += 10; x = p1.GetX(); // x = 6+10 = 16 y = p1.GetY(); // y = 8+10 = 18 Point p3(5,5); p3+=-7; x = p3.GetX(); // x = -2 y = p3.GetY(); // y = -2
⇑
Зв’язані теми
- Перевантаження операторів у C++. Операторна функція. Ключове слово operator. Перевантаження арифметичних операторів +, –, *, /. Приклади реалізації вбудованих операторних функцій
- “Дружні” операторні функції: відмінності, реалізація особливості застосування. Перевантаженняоператорів +, –, *, / з допомогою “дружніх” операторних функцій