21.6 — Przeciążanie operatorów jednoargumentowych +, - i !

Przeciążanie operatorów jednoargumentowych

W przeciwieństwie do operatorów, które widziałeś do tej pory, operatory dodatni (+), ujemny (-) i nie logiczne (!) są operatorami jednoargumentowymi, co oznacza, że ​​działają tylko na jednym operandzie. Ponieważ działają tylko na obiekcie, do którego są zastosowane, zazwyczaj przeciążenia operatora jednoargumentowego są implementowane jako funkcje członkowskie. Wszystkie trzy operatory są implementowane w identyczny sposób.

Przyjrzyjmy się, jak zaimplementowalibyśmy operator – w klasie Cents, której używaliśmy w poprzednim przykładzie:

#include <iostream>

class Cents
{
private:
    int m_cents {};
 
public:
    Cents(int cents): m_cents{cents} {}
 
    // Overload -Cents as a member function
    Cents operator-() const;

    int getCents() const { return m_cents; }
};
 
// note: this function is a member function!
Cents Cents::operator-() const
{
    return -m_cents; // since return type is a Cents, this does an implicit conversion from int to Cents using the Cents(int) constructor
}

int main()
{
    const Cents nickle{ 5 };
    std::cout << "A nickle of debt is worth " << (-nickle).getCents() << " cents\n";

    return 0;
}

To powinno być proste. Nasz przeciążony operator ujemny (-) jest operatorem jednoargumentowym zaimplementowanym jako funkcja składowa, więc nie przyjmuje żadnych parametrów (działa na obiekcie *this). Zwraca obiekt Cents będący negacją oryginalnej wartości Cents. Ponieważ operator- nie modyfikuje obiektu Cents, możemy (i powinniśmy) uczynić z niego funkcję const (aby można było ją wywołać na obiektach const Cents).

Zauważ, że nie ma pomylenia pomiędzy operatorem ujemnym i operatorem minus, ponieważ mają one różną liczbę parametrów.

Oto kolejny przykład. ! operator jest operatorem logicznej negacji — jeśli wyrażenie ma wartość „prawda”, operator! zwróci false i odwrotnie. Często widzimy to w zastosowaniu do zmiennych boolowskich w celu sprawdzenia, czy są one prawdziwe, czy nie:

if (!isHappy)
    std::cout << "I am not happy!\n";
else
    std::cout << "I am so happy!\n";

W przypadku liczb całkowitych 0 daje wartość fałszywą, a wszystko inne – prawdę, więc operator! w zastosowaniu do liczb całkowitych zwróci wartość true dla wartości całkowitej 0, w przeciwnym razie false.

Rozszerzając koncepcję, możemy powiedzieć, że operator! powinien mieć wartość true, jeśli stan obiektu to „false”, „zero” lub jakikolwiek inny domyślny stan inicjalizacji.

Poniższy przykład pokazuje przeciążenie zarówno operatora, jak i operatora! dla zdefiniowanej przez użytkownika klasy Point:

#include <iostream>

class Point
{
private:
    double m_x {};
    double m_y {};
    double m_z {};
 
public:
    Point(double x=0.0, double y=0.0, double z=0.0):
        m_x{x}, m_y{y}, m_z{z}
    {
    }
 
    // Convert a Point into its negative equivalent
    Point operator- () const;

    // Return true if the point is set at the origin
    bool operator! () const;
 
    double getX() const { return m_x; }
    double getY() const { return m_y; }
    double getZ() const { return m_z; }
};

// Convert a Point into its negative equivalent 
Point Point::operator- () const
{
    return { -m_x, -m_y, -m_z };
}

// Return true if the point is set at the origin, false otherwise
bool Point::operator! () const
{
    return (m_x == 0.0 && m_y == 0.0 && m_z == 0.0);
}

int main()
{
    Point point{}; // use default constructor to set to (0.0, 0.0, 0.0)

    if (!point)
        std::cout << "point is set at the origin.\n";
    else
        std::cout << "point is not set at the origin.\n";

    return 0;
}

Przeciążony operator! dla tej klasy zwraca wartość logiczną „true”, jeśli Point ma ustawioną wartość domyślną na współrzędnej (0,0, 0,0, 0,0). Zatem powyższy kod generuje wynik:

point is set at the origin.

Czas quizu

  1. Implementacja przeciążona jednoargumentowa operator+ dla klasy Point. Jednoargumentowy operator+ po prostu zwraca swój operand (nie powoduje to, że wartości ujemne stają się dodatnie).

Pokaż rozwiązanie

guest
Twój adres e-mail nie zostanie wyświetlony
Znalazłeś błąd? Zostaw komentarz powyżej!
Komentarze związane z poprawkami zostaną usunięte po przetworzeniu, aby pomóc zmniejszyć bałagan. Dziękujemy za pomoc w ulepszaniu witryny dla wszystkich!
Awatary z https://gravatar.com/ są połączone z podanym adresem e-mail.
Powiadamiaj mnie o odpowiedziach:  
191 Komentarze
Najnowsze
Najstarsze Najczęściej głosowane
Wbudowane opinie
Wyświetl wszystkie komentarze