Wprowadzenie do przeciążania operatorów
Część sekcji Programowanie obiektowe ścieżki C++ w Coddy. Lekcja 40 z 104.
Przeciążanie operatorów pozwala określić, jak operatory takie jak +, - czy == zachowują się w przypadku użycia z własnymi klasami. Zamiast wywoływać metody takie jak a.add(b), możesz napisać bardziej intuicyjnie a + b.
W C++ operatory są zasadniczo funkcjami o specjalnych nazwach. Aby przeciążyć operator, definiujesz funkcję, używając słowa kluczowego operator, po którym następuje symbol:
class Vector2D {
double x, y;
public:
Vector2D(double x, double y) : x(x), y(y) {}
// Przeciąż operator +
Vector2D operator+(const Vector2D& other) const {
return Vector2D(x + other.x, y + other.y);
}
};Teraz możesz naturalnie dodać dwa wektory:
Vector2D v1(1.0, 2.0);
Vector2D v2(3.0, 4.0);
Vector2D v3 = v1 + v2; // Wywołuje v1.operator+(v2)Nie wszystkie operatory można przeciążać. Operator rozwiązywania zakresu ::, operator dostępu do składowych ., operator trójargumentowy ?: i sizeof nie mogą być przeciążane. Ponadto nie można tworzyć nowych operatorów ani zmieniać priorytetu operatora — * zawsze będzie obliczany przed +.
Operatory można zaimplementować jako funkcje składowe (jak powyżej) lub jako funkcje nieskładowe. W kolejnych lekcjach dowiesz się, kiedy stosować każde z tych podejść i jak przeciążać określone kategorie operatorów.
Wyzwanie
ŁatwyZbudujemy klasę Point, która reprezentuje współrzędne 2D i umożliwia dodawanie dwóch punktów za pomocą operatora +. To Twój pierwszy krok w kierunku przeciążania operatorów, dzięki któremu własne klasy mogą działać z dobrze znanymi operatorami.
Utworzysz dwa pliki, aby uporządkować kod:
Point.h: Zdefiniuj klasęPoint, która przechowuje współrzędne x i y (obie typuint). Twoja klasa powinna mieć:- Prywatne składowe przechowujące współrzędne x i y
- Konstruktor przyjmujący wartości x i y
- Gettery
getX()igetY()(oba const) - Przeciążony operator
+, który dodaje do siebie dwa punkty i zwraca nowy obiektPointo zsumowanych współrzędnych
Operator
+powinien być zaimplementowany jako funkcja składowa, która przyjmuje inny obiektPointprzez referencję const i zwraca nowy obiektPoint. Oznacz go jakoconst, ponieważ nie modyfikuje żadnego z operandów.main.cpp: Odczytaj z wejścia cztery liczby całkowite (x1, y1, x2, y2 w osobnych wierszach) reprezentujące dwa punkty. Utwórz dwa obiektyPoint, dodaj je do siebie za pomocą operatora+i wyświetl wyniki.Format wyjściowy:
Point 1: (<x1>, <y1>) Point 2: (<x2>, <y2>) Sum: (<sum_x>, <sum_y>)
Kluczowa jest tu świadomość, że p1 + p2 w rzeczywistości wywołuje p1.operator+(p2) w tle. Przeciążony operator pozwala pisać intuicyjny kod, na przykład Point p3 = p1 + p2;, zamiast czegoś w rodzaju Point p3 = p1.add(p2);.
Konwertuj ciągi wejściowe na liczby całkowite za pomocą std::stoi(). Nie zapomnij o strażnikach nagłówka w pliku nagłówkowym.
Spróbuj swoich sił
#include <iostream>
#include <string>
#include "Point.h"
using namespace std;
int main() {
// Wczytaj dane wejściowe
string line1, line2, line3, line4;
getline(cin, line1);
getline(cin, line2);
getline(cin, line3);
getline(cin, line4);
int x1 = stoi(line1);
int y1 = stoi(line2);
int x2 = stoi(line3);
int y2 = stoi(line4);
// TODO: Utwórz dwa obiekty Point na podstawie wartości wejściowych
// TODO: Dodaj do siebie dwa punkty za pomocą operatora +
// TODO: Wyświetl wyniki w wymaganym formacie:
// Punkt 1: (<x1>, <y1>)
// Punkt 2: (<x2>, <y2>)
// Suma: (<sum_x>, <sum_y>)
return 0;
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrzneBudowanie i kompilacja C++Pliki nagłówkowe i pliki źródłowePrzestrzenie nazw i zakresWprowadzenie do programowania obiektowego w C++Klasy a obiektyWskaźnik „this”Metody (funkcje składowe)Atrybuty (składowe danych)Podstawy konstruktorów i destruktorówPowtórzenie – prosty kalkulator4Właściwości klas
Elementy instancji a elementy statyczneGettery i setteryStałe funkcje składoweSłowo kluczowe mutableMetody i zmienne statyczneFunkcje i klasy zaprzyjaźnionePodsumowanie – menedżer konta bankowego7Dziedziczenie
Podstawy dziedziczeniaPoziomy dostępu w dziedziczeniuKolejność wywołań konstruktora i destruktoraNadpisywanie metodFunkcje wirtualne i VTableWielokrotne dziedziczenieDziedziczenie wirtualnePowtórzenie — hierarchia pracowników2Zarządzanie pamięcią
Pamięć stosu a stertyWskaźniki i referencjePamięć dynamiczna (new/delete)Inteligentne wskaźniki w C++RAII w C++Podsumowanie — menedżer tablicy dynamicznej5Hermetyzacja
Specyfikatory dostępu w C++Specyfikatory dostępu — szczegółowoUkrywanie informacjiStruktura a klasaKlasy zagnieżdżone i wewnętrznePodsumowanie — system ewidencji studentów8Polimorfizm
Polimorfizm czasu kompilacji i wykonaniaPrzeciążanie funkcjiFunkcje wirtualne — powtórkaCzysto wirtualne funkcjeKlasy abstrakcyjneProjektowanie interfejsów w C++Rzutowanie dynamiczne i RTTIPodsumowanie — kalkulator kształtów3Konstruktory i destruktory
Konstruktor domyślnyKonstruktor z parametramiKonstruktor kopiującyKonstruktor przenoszącyListy inicjalizacyjne konstruktoraKonstruktory delegująceDestruktor — szczegółowe omówienieZasada trzech / pięciu / zeraPodsumowanie — klasa String6Przeciążanie operatorów
Wprowadzenie do przeciążania operatorówPrzeciążanie operatorów arytmetycznychPrzeciążanie operatorów porównaniaOperatory strumieniowePrzeciążanie operatora przypisaniaPrzeciążanie operatorów [] i ()Operatory konwersji typówPodsumowanie — klasa Matrix9Szablony
Szablony funkcjiSzablony klasSpecjalizacja szablonówSzablony wariadycznePodstawy SFINAE i cech typówPodsumowanie — kontener generycznyPoćwicz samodzielnie: Kompilator C++ online