Kursinnhold
C++ OOP
C++ OOP
Operatoroverlasting
Operatoroverlasting er en kraftig funksjon i objektorienterte programmeringsspråk som lar deg omdefinere oppførselen til operatorer for brukerdefinerte classes
. Ved å overbelaste operatorer kan du gi tilpassede implementasjoner for operasjoner som involverer objekter av din class
, noe som gir mer intuitiv og uttrykksfull kode.
Syntaksen for operatoroverlasting
Overlasting oppnås ved å definere spesielle medlemsfunksjoner eller venn-funksjoner som implementerer ønsket oppførsel for operatoren. Syntaksen for å overbelaste operatorer varierer avhengig av hvilken operator du ønsker å overbelaste. Den generelle syntaksen ser slik ut:
overloading.h
return_type operator operator_symbol(parameters);
Syntaksen, eller mer spesifikt, antall parametere og returtype, avhenger også av om du overbelaster operatorer som medlemsfunksjoner eller venn-funksjoner.
Member.h
Friend.h
class Example { public: Example operator+ (const Example& other) { // Define behavior for operator+ } };
Tabell over operatorer som kan overbelastes
Her er en tabell som viser alle operatorene som kan overbelastes. Det er imidlertid viktig å merke seg at selv om det er mulig å overbelaste disse operatorene, er det på ingen måte nødvendig å overbelaste alle for dine classes
.
Overlasting av strøminnsettingsoperatorer
For å overbelaste <<
og >>
-operatorene for en class
, defineres vanligvis en venn-funksjon eller en medlemsfunksjon som tar en utstrøm (std::ostream&
) eller innstrøm (std::istream&
) som venstre operand og et objekt av din class
som høyre operand. Denne funksjonen formaterer deretter objektets data og strømmer det til eller fra strømmen.
Point.h
class Point { public: friend std::ostream& operator<<(std::ostream& out, const Point& point); friend std::istream& operator>>(std::istream& in, Point& point); private: int x, y; }; std::ostream& operator<<(std::ostream& out, const Point& point) { return out << "x: " << point.x << ", y: " << point.y << std::endl; } std::istream& operator>>(std::istream& in, Point& point) { return in >> point.x >> point.y; }
Overlasting av strøminnsettingsoperatorer, som <<
, gjør det mulig å definere tilpasset utdataoppførsel for objekter av dine classes
når de sendes til en utstrøm som std::cout
. Denne funksjonaliteten er spesielt nyttig for å forbedre lesbarheten og brukervennligheten av koden din når du arbeider med egendefinerte datatyper.
Overlasting av <<
-operatoren for utdatastrøm er vanligere enn overlasting av >>
-operatoren for inndatastrøm, fordi inndataoperasjoner med >>
kan være mer feilutsatte.
Overlasting av aritmetiske operatorer
Du kan overbelaste andre aritmetiske operatorer (-
, *
, /
, %
) på lignende måte for å utføre tilpassede operasjoner med dine egendefinerte typer.
main.cpp
#include <iostream> class Point { public: Point(int xCoord, int yCoord) : x(xCoord), y(yCoord) {} Point operator+(const Point& other) { return Point(x + other.x, y + other.y); } int getX() { return x; } int getY() { return y; } private: int x, y; }; int main() { Point p = Point(2, 4) + Point(2, 6); std::cout << p.getX() << ' ' << p.getY() << std::endl; }
Operatoren er overbelastet som en medlemsfunksjon i Point
class
. Den tar et annet Point
objekt som parameter og returnerer et nytt Point
objekt som representerer summen av de to punktene. +
-operatoren kan erstattes med -
, *
, /
eller %
, med tilsvarende justeringer i implementasjonslogikken.
Inkrement og dekrement
Både prefiks og postfiks inkrement- og dekrementoperatorer (++
og --
) kan overbelastes for egendefinerte classes
. La oss begynne med prefiksversjonen:
main.cpp
#include <iostream> class Point { public: Point(int xCoord, int yCoord) : x(xCoord), y(yCoord) {} // Prefix increment operator (++point) Point& operator++() { ++x; ++y; return *this; } int getX() { return x; } int getY() { return y; } private: int x, y; }; int main() { Point p(2, 2); ++p; std::cout << p.getX() << ' ' << p.getY() << std::endl; }
Decrement-operatoren overlastes på en lignende måte som inkrement-operatoren, ved å bruke --
-operatoren og subtraksjonsoperasjonen.
Som du ser, er overlasting av prefiks inkrement- og decrement-operatorene rett fram. Det blir derimot mer komplisert med postfiks-versjonene. Husk at det er en forskjell i rekkefølgen på utførelsen mellom prefiks- og postfiks-operasjoner.
Når vi overbelaster postfiks inkrement og decrement må vi også implementere funksjonaliteten for rekkefølge på utførelsen. Det vil se omtrent slik ut:
main.cpp
#include <iostream> class Point { public: Point(int xCoord, int yCoord) : x(xCoord), y(yCoord) {} // Postfix increment operator (point++) Point operator++(int) { Point temp = *this; // Creating a temp variable ++(this->x); // Incrementing original Point's x ++(this->y); // Incrementing original Point's y return temp; // Returning created temp variable } int getX() { return x; } int getY() { return y; } private: int x, y; }; int main() { Point p(2, 2); p++; std::cout << p.getX() << ' ' << p.getY() << std::endl; }
Heltallsparameteren sendes uten navn kun for å signalisere til kompilatoren at postfiks inkrement-operatoren overlastes. Dette er nødvendig fordi deklarasjonene for prefiks- og postfiksoperatorene ellers er identiske.
I implementasjonen av postfiks inkrement-operatoren lagres den opprinnelige verdien til objektet i en midlertidig variabel (temp
). Det nåværende objektet blir deretter inkrementert, men operatoren returnerer verdien som er lagret i temp
. Dette betyr at variabelen blir inkrementert, men endringen trår først i kraft i neste uttrykk, ettersom operatoren returnerer den opprinnelige verdien.
Takk for tilbakemeldingene dine!