Operatoroverbelastning
Operatoroverbelastning er en kraftfuld funktion i objektorienterede programmeringssprog, der gør det muligt at omdefinere operatorers adfærd for brugerdefinerede classes. Ved at overbelaste operatorer kan du levere tilpassede implementeringer for operationer, der involverer objekter af din class, hvilket muliggør mere intuitiv og udtryksfuld kode.
Syntaksen for operatoroverbelastning
Overbelastning opnås ved at definere specielle medlemsfunktioner eller vennefuktioner, der implementerer den ønskede adfærd for operatoren. Syntaksen for at overbelaste operatorer varierer afhængigt af, hvilken operator du ønsker at overbelaste. Den generelle syntaks ser således ud:
overloading.h
1return_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
Friend.h
123456class 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 outputstream (std::ostream&) eller inputstream (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
123456789101112131415class 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 tilpasset outputadfærd for objekter af dine classes, når de sendes til en outputstream som std::cout. Denne funktion er især nyttig for at forbedre læsbarheden og anvendeligheden af din kode, når du arbejder med brugerdefinerede datatyper.
Overbelastning af <<-operatoren for output stream er mere almindelig end overbelastning 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 egne typer.
main.cpp
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.
Inkrement og dekrement
Både præfiks og postfiks inkrement- og dekrementoperatorerne (++ og --) kan overbelastes for brugerdefinerede classes. Lad os begynde med præfiks-versionen:
main.cpp
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; }
Dekrement-operatoren overbelastes på samme måde som inkrement-operatoren, ved brug af ---operatoren og subtraktionsoperationen.
Som det kan ses, er overbelastning af præfiks inkrement- og dekrement-operatorer ligetil. Det bliver dog mere komplekst med postfiks versionerne. Bemærk, at der er forskel i rækkefølgen af udførelse mellem præfiks og postfiks operationer.
Ved overbelastning af postfiks inkrement og dekrement skal man også implementere rækkefølgen af udførelse. Det vil se nogenlunde sådan ud:
main.cpp
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; }
Det heltalsparameter videregives 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 inkrementeres derefter, men operatoren returnerer værdien gemt i temp. Dette betyder, at variablen inkrementeres, men ændringen træder først i kraft i det næste udtryk, da operatoren returnerer den oprindelige værdi.
Tak for dine kommentarer!
Spørg AI
Spørg AI
Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat
Can you explain the difference between overloading as a member function and as a friend function?
Could you provide an example of overloading the stream insertion operator?
What are some best practices when overloading operators?
Awesome!
Completion rate improved to 3.13
Operatoroverbelastning
Stryg for at vise menuen
Operatoroverbelastning er en kraftfuld funktion i objektorienterede programmeringssprog, der gør det muligt at omdefinere operatorers adfærd for brugerdefinerede classes. Ved at overbelaste operatorer kan du levere tilpassede implementeringer for operationer, der involverer objekter af din class, hvilket muliggør mere intuitiv og udtryksfuld kode.
Syntaksen for operatoroverbelastning
Overbelastning opnås ved at definere specielle medlemsfunktioner eller vennefuktioner, der implementerer den ønskede adfærd for operatoren. Syntaksen for at overbelaste operatorer varierer afhængigt af, hvilken operator du ønsker at overbelaste. Den generelle syntaks ser således ud:
overloading.h
1return_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
Friend.h
123456class 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 outputstream (std::ostream&) eller inputstream (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
123456789101112131415class 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 tilpasset outputadfærd for objekter af dine classes, når de sendes til en outputstream som std::cout. Denne funktion er især nyttig for at forbedre læsbarheden og anvendeligheden af din kode, når du arbejder med brugerdefinerede datatyper.
Overbelastning af <<-operatoren for output stream er mere almindelig end overbelastning 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 egne typer.
main.cpp
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.
Inkrement og dekrement
Både præfiks og postfiks inkrement- og dekrementoperatorerne (++ og --) kan overbelastes for brugerdefinerede classes. Lad os begynde med præfiks-versionen:
main.cpp
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; }
Dekrement-operatoren overbelastes på samme måde som inkrement-operatoren, ved brug af ---operatoren og subtraktionsoperationen.
Som det kan ses, er overbelastning af præfiks inkrement- og dekrement-operatorer ligetil. Det bliver dog mere komplekst med postfiks versionerne. Bemærk, at der er forskel i rækkefølgen af udførelse mellem præfiks og postfiks operationer.
Ved overbelastning af postfiks inkrement og dekrement skal man også implementere rækkefølgen af udførelse. Det vil se nogenlunde sådan ud:
main.cpp
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; }
Det heltalsparameter videregives 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 inkrementeres derefter, men operatoren returnerer værdien gemt i temp. Dette betyder, at variablen inkrementeres, men ændringen træder først i kraft i det næste udtryk, da operatoren returnerer den oprindelige værdi.
Tak for dine kommentarer!