Przeciążenie w C ++

Przeciążenie w C ++
C ++ nie zezwala na funkcję, która dodaje dwie liczby całkowite i zwraca liczbę całkowitą, aby dodać dwa pływaki i zwrócić pływak. Wyobraź sobie, że istnieje funkcja dodania dwóch liczb całkowitych i zwrócenia liczby całkowitej. Czy nie byłoby miło mieć inną funkcję o tej samej nazwie, która dodaje tylko dwa lub jeszcze więcej pływaków, aby zwrócić pływak? Mówi się, że jest to przeciążenie pierwszej funkcji.

Operatorzy arytmetyczne są zwykle stosowane do operacji arytmetycznych. Czy nie jest miło mieć +, dołącz do dwóch sznurków? Włączanie, które mówi się, że przeciąża operator dodatku arytmetycznego dla strun.

Operator przyrostowy, ++ dodaje 1 do INT lub Float. W radzeniu sobie z wskaźnikami nie dodaje 1 do wskaźnika. To sprawia, że ​​wskaźnik wskazuje na następny obiekt z rzędu w pamięci. Iterator wskazuje na następny obiekt w połączonej liście, ale obiekty z listy połączonej znajdują się w różnych miejscach w pamięci (nie w kolejnych regionach). Czy nie byłoby miło przeładować operatora przyrostu dla iteratora, aby zwiększyć, ale wskazywać na następujący element, na liście połączonej?

Ten artykuł wyjaśnia przeciążenie w C++. Jest podzielony na dwie części: przeciążenie funkcji i przeciążenie operatora. Posiadanie już podstawowej wiedzy w C ++ jest konieczne, aby zrozumieć resztę artykułu.

Treść artykułu

  • Przeciążenie funkcji
  • Przeciążenie operatora
  • Przykładowe przeciążenie operatora klasy ciągu
  • Przeciążenie operatora iteratora
  • Wniosek

Przeciążenie funkcji

Poniższa funkcja dodaje dwa ints i zwraca int:

int add (int no1, int no2)

int sum = NO1 + NO2;
suma zwrotu;

Prototypem tej funkcji jest:

int add (int no1, int no2);

Prototyp funkcji w nagłówku funkcji, kończąc na półkolisie. Poniższa funkcja o tej samej nazwie, ale z innym prototypem, dodałaby trzy pływaki i zwróci Float:

Float Add (float no1, float no2, float no3)

float sum = NO1 + NO2 + NO3;
suma zwrotu;

W jaki sposób kompilator różnicuje, która funkcja wywołuje, ponieważ dwie lub więcej funkcji ma tę samą nazwę? Kompilator używa liczby argumentów i typów argumentów, aby określić, która funkcja 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 = add (2, 3);

wywoływałby funkcję liczb całkowitą, podczas gdy funkcja wywołuje,

float SME = dodaj (2.3, 3.4, 2.0);

wywołałby funkcję zmiennoprzecinkową. Uwaga: Istnieją 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 wprowadza powyższe segmenty kodu:

#włączać
za pomocą przestrzeni nazw Std;
int add (int no1, int no2)

int sum = NO1 + NO2;
suma zwrotu;

Float Add (float no1, float no2, float no3)

float sum = NO1 + NO2 + NO3;
suma zwrotu;

int main ()

int sm = add (2, 3);
Cout<float SME = dodaj (2.3, 3.4, 2.0);
Cout<powrót 0;

Wyjście to:

5
7.7

Przeciążenie operatora

Operatorzy arytmetyczne są używane do przeciążenia operacji w typach klas. Iterator to typ klasy. Operatory przyrostu i zmniejszenia są używane do przeciążenia operacji dla iteratora.

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

Ta sekcja zawiera przykład, w którym + jest przeciążony dla po prostu zaprojektowanej klasy ciągów, zwany klasą wiosenną. + łączy literały dwóch obiektów sznurków, zwracając nowy obiekt z połączonymi literałami. Połączenie dwóch literałów oznacza dołączenie do drugiego literatu do końca pierwszego dosłownego.

Teraz C ++ ma specjalną funkcję członka dla wszystkich klas, zwana 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.

#włączać
za pomocą przestrzeni nazw Std;
Spring klasy

publiczny:
// Członkowie danych
Char Val [100];
int n;
char conat [100];
// Funkcje członków
Spring (Char Arr [])

dla (int i = 0; i<100; ++i)
val [i] = arr [i];
if (arr [i] == '\ 0')
przerwa;

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

Spring Operator+(Spring & St)
int newlen = n + st.N;
Char Newstr [Newlen+1];
dla (int i = 0; ifor (int i = n; iNewstr [newlen] = '\ 0';
Spring OBJ (Newstr);
powrót obj;

;
int main ()

char cH1 [] = "Nienawidzę cię! "; Spring Str1 (CH1);
char cH2 [] = "ale ona cię kocha!"; Spring Str2 (CH2);
char cH3 [] = "one"; Spring STR3 (CH3);
str3 = str1 + str2;
Cout<powrót 0;

Wartość STR1 to „Nienawidzę cię! ". Wartość STR2 brzmi: „Ale ona cię kocha!". Wartość STR3, czyli Str1 + Str2, jest wyjściem:

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

który jest połączeniem dwóch literałów smyczkowych. Same struny są instancjami.

Definicja funkcji operatora znajduje się wewnątrz opisu (definicji) klasy ciągu. Zaczyna się od typu powrotu „Spring” dla „ciągu”. Specjalna nazwa „Operator, śledź to”. Następnie istnieje symbol operatora (do przeciążenia). Następnie jest lista parametrów, która w rzeczywistości jest listą operand. + jest operatorem binarnym: co oznacza, że ​​zajmuje lewą i prawą operandę. Jednak według specyfikacji C ++ lista parametrów tutaj ma tylko odpowiedni parametr. Następnie istnieje organ funkcji operatora, która naśladuje zachowanie zwykłego operatora.

Według specyfikacji C ++ definicja operatora+ przyjmuje tylko prawy parametr operandu, ponieważ reszta opisu klasy jest lewym parametrem operandowym.

W powyższym kodzie tylko definicja funkcji operatora + () dotyczy przeciążenia +. Reszta kodu dla klasy to normalne kodowanie. W tej definicji dwa literały sznurkowe są połączone z tablicą, Newsttr []. Następnie tworzony jest nowy obiekt ciąg. Na końcu definicji funkcji operatora+() zwracany jest nowo utworzony obiekt, posiadający połączony ciąg.

W funkcji Main () Dodatek odbywa się w oświadczeniu:

str3 = str1 + str2;

Gdzie Str1, Str2 i Str3 są obiektami ciągami, które zostały już utworzone w Main (). Wyrażenie „STR1 +STR2” z jego +, wywołuje funkcję elementu operatora +() w obiekcie STR1. Funkcja członka operatora+() w obiekcie STR1 używa STR2 jako jego argumentu i zwraca nowy obiekt z (opracowanym) ciągłym ciągiem. Operator przypisania (=) pełnej instrukcji zastępuje zawartość (wartości zmiennych) obiektu Str3, z wartościami zwróconego obiektu. W funkcji Main () po dodaniu wartości elementu danych STR3.Val nie jest już „jednym”; Jest to ciąg (dodany) ciąg: „Nienawidzę cię! Ale ona cię kocha!". Funkcja członka operatora+() w obiekcie STR1 używa literału sznurka własnego obiektu, a literał sznurkowy jego argumentu, STR2, aby wymyślić połączony literał sznurkowy.

Przeciążenie operatora iteratora

W radzeniu sobie z iteratorem zaangażowane są co najmniej dwa obiekty: lista powiązana i sam iterator. W rzeczywistości zaangażowane są co najmniej dwie klasy: klasa, z której utworzona jest lista powiązana, oraz klasa, z której instancja jest instancja iterator.

Połączona lista

Schemat podwójnie połączonej listy jest:

Ta lista ma trzy elementy, ale może być więcej. Trzy elementy tutaj są elementami liczb całkowitych. Pierwszy ma wartość, 14; Następny ma wartość, 88; a ostatni ma wartość, 47. Każdy element składa się z trzech kolejnych lokalizacji.

Jest to inaczej niż tablica, w której każdy element jest jednym z lokalizacji, 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 kolejnych lokalizacji.

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. Dla ostatniego elementu właściwa lokalizacja wskazuje na teoretyczny koniec listy. W przypadku pierwszego elementu lewa lokalizacja wskazuje na teoretyczny początek listy.

Za pomocą tablicy operator przyrostowy (++) zwiększa wskaźnik, aby wskazać fizycznie następną lokalizację. Z listą elementy nie znajdują się w kolejnych regionach w pamięci. Tak więc operator przyrostowy może być przeciążony, przesuń iterator (wskaźnik) z jednego elementu do następnego elementu logicznie. Ta sama projekcja dotyczy operatora spadku (-).

Iterator do przodu jest iteratorem, który po zaangażowaniu wskazuje na następny element. Odwrotny iterator jest iteratorem, który po zaangażowaniu wskazuje na poprzedni element.

Przeciążenie ++ reklamę -

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

Składnia prototypu przeciążenia operatora przyrostowego, prefiks, wynosi

ReturnType Operator ++ ();

Składnia prototypu przeciążenia operatora przyrostowego, postfix, jest

ReturnType Operator ++ (int);

Składnia prototypu przeciążenia operatora zmniejszania, prefiks, wynosi

Powracający operator-();

Składnia prototypu przeciążenia operatora przyrostowego, postfix, jest

Powracający operator-(int);

Wniosek

Przeciążenie oznacza nadanie innego znaczenia funkcji lub operatorowi. Funkcje są przeciążone w tym samym zakresie. To, co odróżnia funkcje przeciążone to liczba i/lub typy parametrów na ich listach parametrów. W niektórych przypadkach, w których liczba parametrów jest taka sama, ale z różnymi typami kompilator odrzuca przeciążenie - patrz później. Wielu zwykłych operatorów może być przeciążonych w klasach, z których obiekty są tworzone. Odbywa się to, podając typ powrotu, listę parametrów i korpus do specjalnej funkcji o nazwie, operator, w opisie klasy.