Kurssisisältö
C++ OOP
C++ OOP
Operaattorin Ylikuormitus
Operaattorien ylikuormitus on tehokas ominaisuus olio-ohjelmointikielissä, jonka avulla voit määritellä operaattoreiden toiminnan uudelleen käyttäjän määrittelemille classes
. Ylikuormittamalla operaattoreita voit tarjota räätälöityjä toteutuksia operaatioille, jotka koskevat class
olioita, mahdollistaen intuitiivisemman ja ilmeikkäämmän koodin.
Operaattorien ylikuormituksen syntaksi
Ylikuormitus toteutetaan määrittelemällä erityisiä jäsenfunktioita tai ystäväfunktioita, jotka toteuttavat halutun toiminnallisuuden operaattorille. Operaattorien ylikuormituksen syntaksi vaihtelee sen mukaan, mitä operaattoria haluat ylikuormittaa. Yleinen muoto näyttää tältä:
overloading.h
return_type operator operator_symbol(parameters);
Syntaksi, eli tarkemmin sanottuna parametrien määrä ja palautustyyppi, riippuvat myös siitä, ylikuormitatko operaattoreita jäsenfunktioina vai ystäväfunktioina.
Member.h
Friend.h
class Example { public: Example operator+ (const Example& other) { // Define behavior for operator+ } };
Ylikuormitettavien operaattoreiden taulukko
Alla on taulukko kaikista operaattoreista, jotka voidaan ylikuormittaa. On kuitenkin tärkeää huomata, että vaikka näiden operaattoreiden ylikuormittaminen on mahdollista, kaikkia ei ole lainkaan pakko ylikuormittaa omille classes
.
Virran lisäysoperaattoreiden ylikuormitus
Ylikuormittaaksesi <<
ja >>
-operaattorit class
-tyypille, määrittelet tyypillisesti ystäväfunktion tai jäsenfunktion, joka ottaa tulostusvirran (std::ostream&
) tai syötevirran (std::istream&
) vasemmaksi operandiksi ja oikeaksi operandiksi class
-olion. Tämä funktio muotoilee olion tiedot ja siirtää ne virtaan tai virrasta.
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; }
Virran lisäysoperaattoreiden, kuten <<
, ylikuormitus mahdollistaa oman tulostuskäyttäytymisen määrittelyn classes
olioille, kun niitä siirretään tulostusvirtaan, kuten std::cout
. Tämä ominaisuus on erityisen hyödyllinen parantamaan koodin luettavuutta ja käytettävyyttä työskenneltäessä omien tietotyyppien kanssa.
<<
-operaattorin ylikuormittaminen tulostusvirralle on yleisempää kuin >>
-operaattorin ylikuormittaminen syötevirralle, koska syöteoperaatiot >>
-operaattorilla voivat olla virhealttiimpia.
Aritmeettisten operaattoreiden ylikuormittaminen
Voit ylikuormittaa myös muita aritmeettisia operaattoreita (-
, *
, /
, %
) samalla tavalla suorittaaksesi mukautettuja operaatioita omilla tietotyypeilläsi.
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; }
Operaattori ylikuormitetaan jäsenfunktiona Point
class
. Se ottaa parametrinaan toisen Point
-olion ja palauttaa uuden Point
-olion, joka edustaa kahden pisteen summaa. +
-operaattori voidaan korvata -
, *
, /
tai %
-operaattorilla, jolloin toteutuslogiikka tulee muokata vastaavasti.
Inkrementointi ja dekrementointi
Sekä etuliite- että jälkiliiteinkrementti- ja dekrementtioperaattorit (++
ja --
) voidaan ylikuormittaa omille classes
. Aloitetaan etuliiteversiosta:
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; }
Vähennysoperaattori ylikuormitetaan samalla tavalla kuin lisäysoperaattori, käyttämällä --
-operaattoria ja vähennyslaskua.
Kuten huomaat, etuliitteisten lisäys- ja vähennysoperaattoreiden ylikuormittaminen on suoraviivaista. Kuitenkin jälkiliitteisten versioiden kanssa se on monimutkaisempaa. Muista, että suorituksen järjestyksessä on ero etuliitteen ja jälkiliitteen välillä.
Kun ylikuormitetaan jälkiliitteisiä lisäys- ja vähennysoperaattoreita, täytyy myös toteuttaa suorituksen järjestysominaisuus. Se näyttää suunnilleen tältä:
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; }
Kokonaislukuparametri välitetään ilman nimeä ainoastaan osoittamaan kääntäjälle, että jälkiliitteinen inkrementtioperaattori ylikuormitetaan. Tämä on tarpeen, koska etuliitteisten ja jälkiliitteisten operaattoreiden määrittelyt ovat muuten identtiset.
Jälkiliitteisen inkrementtioperaattorin toteutuksessa alkuperäinen olion arvo tallennetaan väliaikaiseen muuttujaan (temp
). Nykyistä oliota kasvatetaan, mutta operaattori palauttaa temp
-muuttujaan tallennetun arvon. Tämä tarkoittaa, että muuttuja kasvaa, mutta muutos tulee voimaan vasta seuraavassa lausekkeessa, koska operaattori palauttaa alkuperäisen arvon.
Kiitos palautteestasi!