Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lære Operatoroverbelastning | Oversigt Over Polymorfi
C++ OOP
course content

Kursusindhold

C++ OOP

C++ OOP

1. Grundlæggende OOP i C++
2. Konstruktører og Destruktører
3. Oversigt Over Indkapsling
4. Oversigt over Arv
5. Oversigt Over Polymorfi

book
Operatoroverbelastning

Operatoroverload er en kraftfuld funktion i objektorienterede programmeringssprog, der gør det muligt at omdefinere operatorers adfærd for brugerdefinerede classes. Ved at overloade operatorer kan du levere brugerdefinerede implementeringer for operationer, der involverer objekter af din class, hvilket muliggør mere intuitiv og udtryksfuld kode.

Syntaksen for operatoroverload

Overload opnås ved at definere specielle medlemsfunktioner eller vennefunktioner, der implementerer den ønskede adfærd for operatoren. Syntaksen for at overloade operatorer varierer afhængigt af, hvilken operator du ønsker at overloade. Den generelle syntaks ser således ud:

overloading.h

overloading.h

copy
1
return_type operator operator_symbol(parameters);

Syntaksen, eller mere specifikt antallet af parametre og returtypen, afhænger også af, om du overbelaster operatorer som medlemsfunktioner eller vennefunktioner.

Member.h

Member.h

Friend.h

Friend.h

copy
123456
class Example { public: Example operator+ (const Example& other) { // Define behavior for operator+ } };

Tabellen over operatorer, der kan overbelastes

Her er en tabel, der viser alle de operatorer, der kan overbelastes. Det er dog vigtigt at bemærke, at selvom det er muligt at overbelaste disse operatorer, er det på ingen måde nødvendigt at overbelaste dem alle for dine classes.

Overbelastning af stream-indføringsoperatorer

For at overbelaste operatorerne << og >> for en class, defineres typisk en friend-funktion eller en medlemsfunktion, der tager en output stream (std::ostream&) eller input stream (std::istream&) som venstre operand og et objekt af din class som højre operand. Denne funktion formaterer derefter objektets data og streamer det til eller fra streamen.

Point.h

Point.h

copy
123456789101112131415
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; }

Overbelastning af stream-indføringsoperatorer, såsom <<, gør det muligt at definere brugerdefineret outputadfærd for objekter af dine classes, når de sendes til en output stream som std::cout. Denne funktion er især nyttig for at øge læsbarheden og anvendeligheden af din kode, når du arbejder med brugerdefinerede datatyper.

Note
Bemærk

Overload af <<-operatoren for output stream er mere almindelig end overload af >>-operatoren for input stream, da inputoperationer med >> kan være mere fejlbehæftede.

Overbelastning af aritmetiske operatorer

Andre aritmetiske operatorer (-, *, /, %) kan overbelastes på lignende måde for at udføre brugerdefinerede operationer med dine brugerdefinerede typer.

main.cpp

main.cpp

copy
12345678910111213141516171819202122
#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 overbelastes som en medlemsfunktion i Point-class. Den tager et andet Point-objekt som parameter og returnerer et nyt Point-objekt, der repræsenterer summen af de to punkter. +-operatoren kan erstattes med -, *, / eller %, med tilsvarende justeringer i implementeringslogikken.

Inkrementering og dekrementering

Både præfiks og postfiks inkrementerings- og dekrementeringsoperatorerne (++ og --) kan overbelastes for brugerdefinerede classes. Lad os begynde med præfiks-versionen:

main.cpp

main.cpp

copy
123456789101112131415161718192021222324
#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; }
Note
Bemærk

Decrement-operatoren overbelastes på samme måde som inkrement-operatoren, ved brug af ---operatoren og subtraktionsoperationen.

Som du kan se, er det ligetil at overbelaste præfiks inkrement- og decrement-operatorerne. Det bliver dog mere kompliceret med postfiks versionerne. Husk, der er forskel på rækkefølgen af udførelse mellem præfiks og postfiks operationer.

Når man overbelaster postfiks inkrement og decrement, skal man også implementere rækkefølgen af udførelsesfunktionen. Det vil se nogenlunde sådan ud:

main.cpp

main.cpp

copy
1234567891011121314151617181920212223242526
#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; }
Note
Bemærk

Det heltalsparameteren overføres uden navn udelukkende for at signalere til compileren, at det er postfix-inkrementoperatoren, der overbelastes. Dette er nødvendigt, fordi deklarationerne for prefix- og postfix-operatorer ellers er identiske.

I implementeringen af postfix-inkrementoperatoren gemmes den oprindelige værdi af objektet i en midlertidig variabel (temp). Det aktuelle objekt bliver derefter inkrementeret, men operatoren returnerer værdien, der er gemt i temp. Dette betyder, at variablen bliver inkrementeret, men ændringen træder først i kraft i det næste udtryk, da operatoren returnerer den oprindelige værdi.

question mark

Hvad betyder operatoroverbelastning?

Select the correct answer

Var alt klart?

Hvordan kan vi forbedre det?

Tak for dine kommentarer!

Sektion 5. Kapitel 4

Spørg AI

expand

Spørg AI

ChatGPT

Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat

course content

Kursusindhold

C++ OOP

C++ OOP

1. Grundlæggende OOP i C++
2. Konstruktører og Destruktører
3. Oversigt Over Indkapsling
4. Oversigt over Arv
5. Oversigt Over Polymorfi

book
Operatoroverbelastning

Operatoroverload er en kraftfuld funktion i objektorienterede programmeringssprog, der gør det muligt at omdefinere operatorers adfærd for brugerdefinerede classes. Ved at overloade operatorer kan du levere brugerdefinerede implementeringer for operationer, der involverer objekter af din class, hvilket muliggør mere intuitiv og udtryksfuld kode.

Syntaksen for operatoroverload

Overload opnås ved at definere specielle medlemsfunktioner eller vennefunktioner, der implementerer den ønskede adfærd for operatoren. Syntaksen for at overloade operatorer varierer afhængigt af, hvilken operator du ønsker at overloade. Den generelle syntaks ser således ud:

overloading.h

overloading.h

copy
1
return_type operator operator_symbol(parameters);

Syntaksen, eller mere specifikt antallet af parametre og returtypen, afhænger også af, om du overbelaster operatorer som medlemsfunktioner eller vennefunktioner.

Member.h

Member.h

Friend.h

Friend.h

copy
123456
class Example { public: Example operator+ (const Example& other) { // Define behavior for operator+ } };

Tabellen over operatorer, der kan overbelastes

Her er en tabel, der viser alle de operatorer, der kan overbelastes. Det er dog vigtigt at bemærke, at selvom det er muligt at overbelaste disse operatorer, er det på ingen måde nødvendigt at overbelaste dem alle for dine classes.

Overbelastning af stream-indføringsoperatorer

For at overbelaste operatorerne << og >> for en class, defineres typisk en friend-funktion eller en medlemsfunktion, der tager en output stream (std::ostream&) eller input stream (std::istream&) som venstre operand og et objekt af din class som højre operand. Denne funktion formaterer derefter objektets data og streamer det til eller fra streamen.

Point.h

Point.h

copy
123456789101112131415
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; }

Overbelastning af stream-indføringsoperatorer, såsom <<, gør det muligt at definere brugerdefineret outputadfærd for objekter af dine classes, når de sendes til en output stream som std::cout. Denne funktion er især nyttig for at øge læsbarheden og anvendeligheden af din kode, når du arbejder med brugerdefinerede datatyper.

Note
Bemærk

Overload af <<-operatoren for output stream er mere almindelig end overload af >>-operatoren for input stream, da inputoperationer med >> kan være mere fejlbehæftede.

Overbelastning af aritmetiske operatorer

Andre aritmetiske operatorer (-, *, /, %) kan overbelastes på lignende måde for at udføre brugerdefinerede operationer med dine brugerdefinerede typer.

main.cpp

main.cpp

copy
12345678910111213141516171819202122
#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 overbelastes som en medlemsfunktion i Point-class. Den tager et andet Point-objekt som parameter og returnerer et nyt Point-objekt, der repræsenterer summen af de to punkter. +-operatoren kan erstattes med -, *, / eller %, med tilsvarende justeringer i implementeringslogikken.

Inkrementering og dekrementering

Både præfiks og postfiks inkrementerings- og dekrementeringsoperatorerne (++ og --) kan overbelastes for brugerdefinerede classes. Lad os begynde med præfiks-versionen:

main.cpp

main.cpp

copy
123456789101112131415161718192021222324
#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; }
Note
Bemærk

Decrement-operatoren overbelastes på samme måde som inkrement-operatoren, ved brug af ---operatoren og subtraktionsoperationen.

Som du kan se, er det ligetil at overbelaste præfiks inkrement- og decrement-operatorerne. Det bliver dog mere kompliceret med postfiks versionerne. Husk, der er forskel på rækkefølgen af udførelse mellem præfiks og postfiks operationer.

Når man overbelaster postfiks inkrement og decrement, skal man også implementere rækkefølgen af udførelsesfunktionen. Det vil se nogenlunde sådan ud:

main.cpp

main.cpp

copy
1234567891011121314151617181920212223242526
#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; }
Note
Bemærk

Det heltalsparameteren overføres uden navn udelukkende for at signalere til compileren, at det er postfix-inkrementoperatoren, der overbelastes. Dette er nødvendigt, fordi deklarationerne for prefix- og postfix-operatorer ellers er identiske.

I implementeringen af postfix-inkrementoperatoren gemmes den oprindelige værdi af objektet i en midlertidig variabel (temp). Det aktuelle objekt bliver derefter inkrementeret, men operatoren returnerer værdien, der er gemt i temp. Dette betyder, at variablen bliver inkrementeret, men ændringen træder først i kraft i det næste udtryk, da operatoren returnerer den oprindelige værdi.

question mark

Hvad betyder operatoroverbelastning?

Select the correct answer

Var alt klart?

Hvordan kan vi forbedre det?

Tak for dine kommentarer!

Sektion 5. Kapitel 4
some-alt