Ponadto badamy różnicę między przeciążaniem a przesuwaniem przy pomocy tabeli porównawczej.
Wykres porównania:
Podstawa do porównania | Przeciążenie | Nadrzędny |
---|---|---|
Prototyp | Prototyp różni się w zależności od liczby lub typu parametru. | Wszystkie aspekty prototypu muszą być takie same. |
Słowo kluczowe | Nie zastosowano słowa kluczowego podczas przeciążania. | Funkcję, która ma zostać zastąpiona, poprzedza słowo kluczowe "wirtualny" w klasie bazowej. |
Czynnik wyróżniający | Liczba lub typ parametru różni się, co decyduje o wywołaniu wersji funkcji. | Funkcja, której klasa jest wywoływana przez wskaźnik, jest określana przez adres obiektu klasy, który jest przypisany do tego wskaźnika. |
Definiowanie wzoru | Funkcja jest przedefiniowana z tą samą nazwą, ale różni się liczbą i typem parametru. | Funkcja jest zdefiniowana, poprzedzona słowem kluczowym "virtual" w klasie głównej i przedefiniowana przez klasę pochodną bez słowa kluczowego out. |
Czas realizacji | Czas kompilacji. | Czas pracy. |
Funkcja Constructor / Virtual | Konstruktory mogą być przeciążone. | Funkcja wirtualna może zostać nadpisana. |
Burzyciel | Destructor nie może być przeciążony. | Destruktor może zostać nadpisany. |
Wiążący | Przeciążenie zapewnia wczesne wiązanie. | Nadpisywanie odnosi się do późnego wiązania. |
Definicja przeciążenia
Polimorfizm w czasie kompilacji nazywany jest "przeciążeniem". Ponieważ przeciążenie jest generowane z koncepcji polimorfizmu, zapewnia "wspólny interfejs dla wielu metod". Oznacza to, że jeśli funkcja jest przeciążona, zawiera ona tę samą nazwę funkcji, gdy jest ona przedefiniowana.
Przeciążone funkcje różnią się pod względem różnej "liczby lub typu parametru (ów)", co powoduje, że jedna przeciążona funkcja różni się od innej. W ten sposób kompilator rozpoznaje, która funkcja jest przeładowana. Najczęściej przeciążonymi funkcjami są "konstruktorzy". "Kopiuj konstruktor" jest rodzajem "przeciążania konstruktora".
Implementacja przeciążania w C ++
przeciążenie klasy {int a, b; public: int load (int x) {// pierwsza funkcja load () a = x; return a; } int load (int x, int y) {// funkcja drugiego obciążenia () a = x; b = y; return a * b; }}; int main () {przeciążenie O1; O1.load (20); // pierwsze wywołanie funkcji load () O1.load (20, 40); // wywołanie funkcji second load ()}
Tutaj przeciążenie funkcji load () przeciążenia klasy zostało przeciążone. Dwie przeciążone funkcje klasy można rozróżnić w taki sposób, że pierwsza funkcja load () akceptuje tylko jeden parametr liczby całkowitej, podczas gdy druga funkcja load () akceptuje dwa parametry całkowite. Gdy obiekt przeciążenia klasy wywołuje funkcję load () z pojedynczym parametrem, wywoływana jest funkcja first load (). Gdy obiekt wywołuje funkcję load () przekazującą dwa parametry, wywoływana jest druga funkcja load ().
Definicja przesłaniania
Polimorfizm osiągnięty podczas biegania nazywany jest "nadrzędnym". Dokonuje się tego za pomocą "dziedziczenia" i "funkcji wirtualnych". Przesłonięcie funkcji poprzedza słowo kluczowe "wirtualna" w klasie bazowej i ponownie zdefiniowane w klasie pochodnej bez żadnego słowa kluczowego.
Jedną z najważniejszych rzeczy do zapamiętania w przypadku przesłonięcia jest to, że prototyp funkcji nadpisanej nie może się zmienić, podczas gdy klasa pochodna przedefiniowuje ją. Gdy nadpisana funkcja otrzyma wywołanie, C ++ ustala, która wersja funkcji jest wywoływana na podstawie "typu obiektu wskazanego przez wskaźnik", za pomocą którego wykonywane jest wywołanie funkcji.
Implementacja nadpisywania w C ++
class base {public: virtual void funct () {// funkcja wirtualna klasy cout << "To jest funkcja klasy podstawowej ()"; }}; pochodna class1: public base {public: void funct () {// funkcja wirtualna klasy bazowej na nowo zdefiniowana w klasie pochodnej1 cout << "Jest to funkcja klasy pochodnej1 ()"; }}; pochodna class2: public base {public: void funct () {// funkcja wirtualna klasy bazowej na nowo zdefiniowana w klasie pochodnej2 coutfunct (); // wywołanie funkcji pochodnej1 (). * p = i d2; p-> funct (); // wywołanie funkcji pochodnej2 class (). return 0; }
Tutaj istnieje jedna klasa bazowa, która jest publicznie dziedziczona przez dwie klasy pochodne. Funkcja wirtualna jest zdefiniowana w klasie bazowej ze słowem kluczowym "wirtualny" i jest ponownie definiowana przez obie klasy pochodne bez słowa kluczowego. W main () klasa podstawowa tworzy zmienną wskaźnika "p" i obiekt "b"; Klasa "deriv1" tworzy obiekt d1, a klasa2 tworzy obiekt d2 '.
Teraz początkowo adres obiektu klasy podstawowej "b" jest przypisany do wskaźnika klasy bazowej "p". "p" wywołuje funkcję funct (), więc wywoływana jest funkcja klasy bazowej. Następnie adres obiektu klasy pochodnej1 "d1" jest przypisany do wskaźnika "p", ponownie wywołuje funkcję funct (); tutaj wykonywana jest funkcja funct () klasy pochodnej1. Wreszcie, wskaźnik "p" jest przypisany do obiektu klasy pochodnej2. Następnie "p" wywołuje funkcję funct (), która wykonuje funkcję func () klasy pochodnej2.
Jeśli wyprowadzona klasa 1 / wyprowadzona2 nie przedefiniuje funct (), wówczas funkcja () klasy bazowej zostałaby wywołana, ponieważ funkcja wirtualna jest "hierarchiczna".
Kluczowe różnice między przeciążeniem a nadpisywaniem
- Prototyp funkcji, która jest przeciążona, różni się ze względu na typ i liczbę parametrów przekazywanych do przeciążonej funkcji. Z drugiej strony prototyp zastąpionej funkcji nie zmienia się, ponieważ zastąpiona funkcja wykonuje inne działanie dla innej klasy, do której należy, ale z tym samym typem i liczbą parametrów.
- Nazwa przeciążonej funkcji nie jest poprzedzona żadnym słowem kluczowym, natomiast nazwa zastąpionej funkcji poprzedza kluczem "Wirtualny" tylko w klasie bazowej.
- Która funkcja przeciążenia jest wywoływana, zależy od typu lub liczby parametru przekazywanego do funkcji. Przesłonięta funkcja, której klasa jest wywoływana, zależy od tego, który adres obiektu klasy jest przypisany do wskaźnika, który wywołał funkcję.
- Która funkcja przeciążona ma zostać wywołana, zostaje rozwiązana podczas kompilacji. Zastąpiona funkcja, która ma zostać wywołana, jest rozwiązywana podczas wykonywania.
- Konstruktory mogą być przeciążone, ale nie można ich przesłonić.
- Destruktory nie mogą być przeciążone, ale można je przesłonić.
- Przeciążanie zapewnia wczesne wiązanie, do którego zostanie wywołana przeciążona funkcja, jest rozwiązywane podczas kompilacji. Nadpisywanie osiąga późne wiązanie, ponieważ funkcja, która zostanie zastąpiona, zostanie wywołana podczas pracy.
Podobieństwa
- Oba są stosowane do funkcji członkowskich klasy.
- Polimorfizm jest podstawową koncepcją kryjącą się za nimi.
- Nazwa funkcji pozostaje taka sama, gdy stosujemy przeciążanie i nadpisywanie funkcji.
Wniosek
Przeciążanie i nadpisywanie wygląda podobnie, ale tak nie jest. Funkcje mogą być przeciążone, ale żadna klasa nie może dalej redefiniować przeciążonej funkcji w przyszłości. Funkcja wirtualna nie może być przeciążona; można je tylko przesłonić.