Розглянемо унарні оператори плюс (+), мінус (-) і логічне НЕ (!), які працюють з одним операндом. Так як вони застосовуються тільки до одного об’єкту, то їх перевантаження слід виконувати через методи класу.
Наприклад, перевантажимо унарний оператор мінус (-) для класу Dollars:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#include <iostream> class Dollars { private: int m_dollars; public: Dollars(int dollars) { m_dollars = dollars; } // Виконуємо -Dollars через метод класу Dollars operator-() const; int getDollars() const { return m_dollars; } }; // Ця функція є методом класу! Dollars Dollars::operator-() const { return Dollars(-m_dollars); } int main() { const Dollars dollars1(7); std::cout << "My debt is " << (-dollars1).getDollars() << " dollars.\n"; return 0; } |
Примітка: Визначення методу можна записати і всередині класу. Тут ми визначили його поза тілом класу для кращої наочності прикладу.
Все досить-таки просто. Перевантаження від’ємного унарного оператора мінус (-) здійснюється через метод класу, так як явні параметри в функції перевантаження відсутні (тільки неявний об’єкт, на який вказує прихований вказівник *this). Оператор - повертає об’єкт Dollars з від’ємним значенням m_dollars. Оскільки цей оператор не змінює об’єкт класу Dollars, то ми можемо (і повинні) зробити функцію перевантаження константною (щоб мати можливість використовувати цей оператор і з константними об’єктами класу Dollars).
Зверніть увагу, плутанини між від’ємним унарним оператором мінус (-) і бінарним оператором мінус (-) немає, так як вони мають різну кількість параметрів.
Ось ще один приклад: оператор ! є логічним оператором НЕ, який повертає true, якщо результатом виразу є false і повертає false, якщо результатом виразу є true. Зазвичай це застосовується до змінних типу bool, щоб перевірити, чи є вони true чи ні:
|
1 2 3 4 |
if (!isHappy) std::cout << "I am not happy!\n"; else std::cout << "I am so happy!\n"; |
У мові С++ значення 0 означає false, а будь-яке інше ненульове значення означає true, тому, якщо логічний оператор ! застосовувати до цілочисельних значень, він повертатиме true, якщо значенням змінної є 0, в протилежному випадку — false.
Отже, при роботі з класами, оператор ! повертатиме true, якщо значенням об’єкта класу є false, 0 або будь-яке інше значення, задане як дефолтне (за замовчуванням) при ініціалізації, в протилежному випадку оператор ! повертатиме false.
У наступному прикладі ми розглянемо перевантаження унарного оператора мінус (−) і оператора логічного НЕ (!) для класу Something:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
#include <iostream> class Something { private: double m_a, m_b, m_c; public: Something(double a = 0.0, double b = 0.0, double c = 0.0) : m_a(a), m_b(b), m_c(c) { } // Конвертуємо об'єкт класу Something у від'ємний Something operator- () const { return Something(-m_a, -m_b, -m_c); } // Повертаємо true, якщо використовуються значення за замовчуванням, в протилежному випадку - false bool operator! () const { return (m_a == 0.0 && m_b == 0.0 && m_c == 0.0); } double getA() { return m_a; } double getB() { return m_b; } double getC() { return m_c; } }; int main() { Something something; // використовуємо конструктор за замовчуванням зі значеннями 0.0, 0.0, 0.0 if (!something) std::cout << "Something is null.\n"; else std::cout << "Something is not null.\n"; return 0; } |
Тут перевантажений оператор НЕ (!) повертає true, якщо в Something використовуються значення за замовчуванням (0.0, 0.0, 0.0).
Результат виконання програми:
Something is null.
Якщо ж задати будь-які ненульові значення для об’єкта класу Something:
|
1 |
Something something(23.11, 37.1, 20.12); |
То результатом буде:
Something is not null.
Тест
Реалізуйте перевантаження унарного оператора плюс (+) для класу Something.
Відповідь
Є два рішення.
Рішення №1:
|
1 2 3 4 |
Something Something::operator+ () const { return Something(m_a, m_b, m_c); } |
Рішення №2:
|
1 2 3 4 |
Something Something::operator+ () const { return *this; } |
Це працює, тому що Something, який ми повертаємо, є поточним об’єктом.
