C++

Przeciążanie w C++

Przeciążanie w C++
C++ nie pozwala funkcji, która dodaje dwie liczby całkowite i zwraca liczbę całkowitą, aby dodać dwie liczby zmiennoprzecinkowe i zwrócić liczbę zmiennoprzecinkową. Wyobraź sobie, że istnieje funkcja dodawania dwóch liczb całkowitych i zwracania liczby całkowitej. Czy nie byłoby miło mieć inną funkcję o tej samej nazwie, która dodaje tylko dwie lub nawet więcej liczb zmiennoprzecinkowych, aby zwrócić liczbę zmiennoprzecinkową? Mówi się, że zrobienie tego jest przeciążeniem pierwszej funkcji.

Operatory arytmetyczne są zwykle używane do operacji arytmetycznych. Czy nie jest miło mieć +, połącz dwie struny?? Włączenie tego jest uważane za przeciążenie operatora dodawania arytmetycznego dla łańcuchów.

Operator inkrementacji, ++ dodaje 1 do int lub float. Kiedy mamy do czynienia ze wskaźnikami, nie dodaje 1 do wskaźnika. Sprawia, że ​​wskaźnik wskazuje na następny kolejny obiekt w pamięci. Iterator wskazuje następny obiekt na połączonej liście, ale obiekty połączonej listy znajdują się w różnych miejscach w pamięci (nie w kolejnych regionach). Czy nie byłoby miło przeciążyć operatora inkrementacji dla iteratora, aby inkrementować, ale wskazywać na następujący element na połączonej liście?

Ten artykuł wyjaśnia przeciążanie w C++. Jest podzielony na dwie części: przeciążanie funkcji i przeciążanie operatora. Znajomość podstaw C++ jest niezbędna do zrozumienia dalszej części artykułu.

Treść artykułu

Przeciążenie funkcji

Poniższa funkcja dodaje dwie wartości typu int i zwraca wartość typu int:

int add(int no1, int no2)

suma int = nr1 + nr2;
suma zwrotu;

Prototyp tej funkcji to:
int add(int nr1, int nr2);
Prototyp funkcji w nagłówku funkcji, zakończony średnikiem. Poniższa funkcja o tej samej nazwie, ale z innym prototypem, doda trzy liczby zmiennoprzecinkowe i zwróci liczbę zmiennoprzecinkową:
float add(float no1, float no2, float no3)

suma zmiennoprzecinkowa = nie1 + nie2 + nie3;
suma zwrotu;

W jaki sposób kompilator rozróżnia, którą funkcję należy wywołać, skoro dwie lub więcej funkcji ma tę samą nazwę?? Kompilator używa liczby argumentów i typów argumentów, aby określić, którą funkcję wywołać. Lista parametrów przeciążonych funkcji powinna różnić się liczbą i/lub typami parametrów. Tak więc wywołanie funkcji,

int sm = dodaj(2, 3);

wywoła funkcję całkowitą, podczas gdy funkcja wywoła,

pływak sme = dodaj(2.3, 3.4, 2.0);

wywołałby funkcję zmiennoprzecinkową. Uwaga: są sytuacje, w których kompilator odrzuci przeciążoną funkcję, gdy liczba argumentów jest taka sama, ale różnych typów! - Powód: - patrz później.

Poniższy program uruchamia powyższe segmenty kodu:

#zawierać
przy użyciu standardowej przestrzeni nazw;
int add(int no1, int no2)

suma int = nr1 + nr2;
suma zwrotu;

float add(float no1, float no2, float no3)

suma zmiennoprzecinkowa = nie1 + nie2 + nie3;
suma zwrotu;

int main()

int sm = dodaj(2, 3);
Cout<pływak sme = dodaj(2.3, 3.4, 2.0);
Cout<zwróć 0;

Dane wyjściowe to:
5
7.7

Przeciążenie operatora

Operatory arytmetyczne służą do przeciążania operacji w typach klas. Iterator jest typem klasy. Operatory inkrementacji i dekrementacji służą do przeciążania operacji dla iteratora.

Przykładowe przeciążenie operatora klasy ciągu

W tej sekcji przedstawiono przykład, w którym + jest przeciążony dla prostej zaprojektowanej klasy łańcucha, zwanej klasą sprężyny. + łączy literały dwóch obiektów napisowych, zwracając nowy obiekt z połączonymi literałami. Łączenie dwóch literałów oznacza łączenie drugiego literału z końcem pierwszego literału.

Teraz C++ ma specjalną funkcję składową dla wszystkich klas, zwaną operatorem. Programista może użyć tej specjalnej funkcji do przeciążenia operatorów, takich jak +. Poniższy program pokazuje przeciążenie operatora + dla dwóch ciągów.

#zawierać
przy użyciu standardowej przestrzeni nazw;
klasa wiosna

publiczny:
//członkowie danych
wartość char[100];
intn;
char concat[100];
//funkcje członków
wiosna (znak arr[])

dla (int i=0; i<100; ++i)
wart[i] = przyp[i];
if (arr[i] == '\0')
złamać;

wew;
dla (i=0; i<100; ++i) if (arr[i] == '\0') break;
n = i;

operator sprężyny+(sprężyna i st)
int newLen = n + st.n;
char nowaStr[nowaDł+1];
dla (int i=0; idla (int i=n; inowaStr[nowaDł] = '\0';
wiosna obj(newStr);
zwróć obj;

;
int main()

char ch1[] = "Nienawidzę cię! "; sprężyna str1(ch1);
char ch2[] = "Ale ona cię kocha!"; sprężyna str2(ch2);
znak ch3[] = "jeden"; sprężyna str3(ch3);
słowo3 = słowo1 + słowo2;
Cout<zwróć 0;

Wartość str1 to „Nienawidzę cię! ". Wartość str2 to „Ale ona cię kocha!". Wartość str3, czyli str1 + str2, jest wynikiem:

"Nienawidzę cię! Ale ona cię kocha!"

czyli konkatenacja dwóch literałów napisowych. Same ciągi są obiektami skonkretyzowanymi.

Definicja funkcji operatora znajduje się w opisie (definicji) klasy string. Zaczyna się od typu zwracanego, „spring” dla „string”. Specjalna nazwa „operator, podążaj za tym”. Po nim jest symbol operatora (do przeciążenia). Następnie jest lista parametrów, która w rzeczywistości jest listą operandów. + jest operatorem binarnym: co oznacza, że ​​przyjmuje lewy i prawy operand. Jednak według specyfikacji C++ lista parametrów tutaj ma tylko właściwy parametr only. Następnie jest ciało funkcji operatora, która naśladuje zachowanie zwykłego operatora.

Zgodnie ze specyfikacją C++, definicja operatora + przyjmuje tylko prawy parametr operandu, ponieważ reszta opisu klasy to lewy parametr operandu.

W powyższym kodzie tylko definicja funkcji operator+() dotyczy + przeciążania. Reszta kodu dla klasy to normalne kodowanie. Wewnątrz tej definicji dwa literały ciągu są połączone w tablicę newStr[]. Następnie tworzony jest nowy obiekt tekstowy (instancja) przy użyciu argumentu newStr[]. Na końcu definicji funkcji operator+() zwracany jest nowo utworzony obiekt, posiadający połączony ciąg znaków.

W funkcji main() dodawanie odbywa się za pomocą instrukcji:

słowo3 = słowo1 + słowo2;

Gdzie str1, str2 i str3 to obiekty łańcuchowe, które zostały już utworzone w main(). Wyrażenie „str1 + str2” z jego + wywołuje funkcję członkowską operator+() w obiekcie str11. Funkcja członkowska operator+() w obiekcie str1 używa str2 jako argumentu i zwraca nowy obiekt z (opracowanym) połączonym ciągiem. Operator przypisania (=) kompletnej instrukcji zastępuje zawartość (wartości zmiennych) obiektu str3 tymi z zwracanego obiektu. W funkcji main() po dodaniu wartość składowej danych str3.val nie jest już „jeden”; jest to połączony (dodawanie) ciąg „Nienawidzę cię! Ale ona cię kocha!". Funkcja członkowska operator+() w obiekcie str1, używa literału ciągu własnego obiektu i literału ciągu swojego argumentu str2 w celu uzyskania połączonego literału ciągu.

Przeciążenie operatora iteratora

Kiedy mamy do czynienia z iteratorem, zaangażowane są co najmniej dwa obiekty: lista połączona i sam iterator. W rzeczywistości zaangażowane są co najmniej dwie klasy: klasa, z której tworzona jest lista połączona, oraz klasa, z której tworzony jest instancja iteratora.

Połączona lista

Diagram dla podwójnie połączonego obiektu listy to:

Ta lista składa się z trzech elementów, ale może być ich więcej. Trzy elementy tutaj są elementami liczb całkowitych. Pierwsza ma wartość 14; następny ma wartość 88; a ostatni ma wartość 47. Każdy element tutaj składa się z trzech następujących po sobie lokacji.

W przeciwieństwie do tablicy, w której każdy element jest jedną lokalizacją, a wszystkie elementy tablicy znajdują się w kolejnych lokalizacjach. Tutaj różne elementy znajdują się w różnych miejscach w serii pamięci, ale każdy element składa się z trzech następujących po sobie miejsc.

Dla każdego elementu środkowa lokalizacja zawiera wartość. Właściwa lokalizacja ma wskaźnik do następnego elementu. Lewa lokalizacja ma wskaźnik do poprzedniego elementu. W przypadku ostatniego elementu właściwa lokalizacja wskazuje na teoretyczny koniec listy. Dla pierwszego elementu lewa lokalizacja wskazuje na teoretyczny początek listy.

W przypadku tablicy operator inkrementacji (++) zwiększa wskaźnik, aby wskazywał na fizycznie następną lokalizację. Z listą elementy nie znajdują się w kolejnych regionach pamięci. Tak więc operator inkrementacji może być przeciążony, przesunąć iterator (wskaźnik) z jednego elementu na logicznie następny element. Ta sama projekcja dotyczy operatora dekrementacji (-).

Iterator do przodu to iterator, który po włączeniu wskazuje następny element. Iterator odwrotny to iterator, który po włączeniu wskazuje na poprzedni element.

Przeciążenie ++ ad -

Przeciążanie tych operatorów odbywa się w opisie klasy (definicji) iteratora.

Składnia prototypu przeciążenia operatora inkrementacji, prefiks, to

Operator ReturnType++();

Składnia prototypu przeciążania operatora przyrostu, postfix, to

Operator ReturnType++(int);

Składnia prototypu przeciążenia operatora dekrementacji, prefiks, to

Operator ReturnType--();

Składnia prototypu przeciążania operatora przyrostu, postfix, to

Operator ReturnType--(int);

Wniosek

Przeciążenie oznacza nadanie innego znaczenia funkcji lub operatorowi. Funkcje są przeciążone w tym samym zakresie. Tym, co odróżnia przeciążone funkcje, jest liczba i/lub typy parametrów na ich listach parametrów. W niektórych przypadkach, gdy liczba parametrów jest taka sama, ale przy różnych typach, kompilator odrzuca przeciążenie - patrz dalej. Wiele zwykłych operatorów może być przeciążonych w klasach, z których tworzone są obiekty. Odbywa się to poprzez podanie typu zwracanego, listy parametrów i treści do funkcji specjalnej o nazwie operator w opisie klasy.

Gry 5 najlepszych kart do przechwytywania gier
5 najlepszych kart do przechwytywania gier
Wszyscy widzieliśmy i uwielbialiśmy strumieniowe rozgrywki na YouTube on. PewDiePie, Jakesepticye i Markiplier to tylko niektórzy z najlepszych graczy...
Gry Jak stworzyć grę na Linuksie
Jak stworzyć grę na Linuksie
Dziesięć lat temu niewielu użytkowników Linuksa przewidywało, że ich ulubiony system operacyjny pewnego dnia stanie się popularną platformą do gier dl...
Gry Open Source Ports of Commercial Game Engines
Open Source Ports of Commercial Game Engines
Free, open source and cross-platform game engine recreations can be used to play old as well as some of the fairly recent game titles. This article wi...