do koszyka |
do koszyka |
do koszyka |
do koszyka |
do koszyka |
do koszyka |
do koszyka |
do koszyka |
do koszyka |
KURS JĘZYKA C++ PODSTAWY
00. Informacje ogólne - wstęp 01. Praca z konsolą - początki - cout 02. Zmienne (int, float, double) 03. Konsola cd. - cin 04. Zmienne tekstowe - (char, string) 05. Operatory 06. Instrukcje warunkowe (if - else, switch - case) 07. Pętle (for, while) 08. Instrukcje warunkowe cd. 09. Break, Continue 10. Funkcje 11. Zakresy ważności 12. Tablice zmiennych 13. Mała powtórka :))) 14. Struct - struktury 15. String, Vector - wstęp do STL 16. Wskaźniki, referencje 16a. Wskaźnik do typów prostych 16b. Wskaźnik do funkcji 16c. Operatory new i delete 16d. Referencje 17. Pliki źródłowe i nagłówkowe Zadania powtórzeniowe 18. Class - klasy 19. Konstruktor , destruktor 20. Argumenty domyślne, przeciążanie (przeładowanie) funkcji i operatorów C++ FAQ: 01. Operacje na plikach, odczyt/zapis02. Nie działa mi polecenie gotoxy() co robić ? 03. Jaki podręcznik do nauki C++ ? ostatnia aktualizacja: 29.08.2005 ARGUMENTY DOMYŚLNE, PRZECIĄŻANIE (PRZEŁADOWANIE) FUNKCJI I OPERATORÓW
Dzisiejsza lekcja to mały dodatek z informacjami które mogą okazać się przydatne, może nie są one niezbędne ale jednak bardzo
ułatwiają czasem życie, oczywiście jeśli wiemy gdzie i jak je zastosować.
ARGUMENTY DOMYŚLNE FUNKCJI Z pojęciem tym jeszcze nie spotkaliśmy się w naszych rozważaniach ale nadszedł najwyższy na to czas gdyż już wkrótce będzie nam to przydatne. Utwórzmy sobie funkcję i załóżmy, że będzie ona przyjmowała dwa argumenty: Na ekranie zobaczymy liczbę 15. Wszystko powinno ładnie działać do momentu gdy okaże się, że w większości wywołań powyższej funkcji jeden z argumentów występuje "podejrzanie" często: Może powyższy przykład nie jest idalny ale za to dobrze obrazuje nasz problem. Jak widzimy w większości przypadków jako drugi parametr (b) podawana jest liczba 5, gdyby zawsze tam była liczba 5 nie byłoby problemu w takim przypadku w ogóle zrezygnować można z drugiego parametru jego wartość umieścić bezpośrednio w funkcji i po sprawie, niestety nie w tym przypadku bo jednak czasem występuje tam inna wartość niż 5. Tu właśnie z pomocą przychodzą nam argumenty domyślne funkcji. Argument domyślny to taki argument który jest wstawiany gdy nie podano niczego... Myślę, że poniższy przykład wyjaśni wszystko. Jak widać w deklaracji funkcji pojawił się zapis int b=5 informuje on o tym, że jeśli przy wywołaniu funkcji nie podamy drugiego parametru to domyślnie zostanie wstawiona liczba 5. Mała rzecz a cieszy :). Każdemu z argumentów funkcji można podać jakąś domyślną wartość ale wiąże sę to z pewnymi konsekwencjami: - może się zdarzyć tak, że po prostu zapomnimy kiedyś podać przy wywołaniu funkcji argumenty a ona i tak zadziała choć jej działanie nie będzie zgodne z naszymi oczekiwaniami - kolejność argumentów przy wywoływaniu funkcji MA znaczenie jeśli np. funkcja test(int a=0,int b=0, int c=0) ma trzy argumenty domyślne to jej wywołanie test(23) spowoduje przekazanie do zmiennej a wartości 23 pozostałe zmienne zostaną wyzerowane, jest to logiczne bo skoro podajemy jedną liczbę a funkcja oczekuje trzech to na jakiej podstawie miała by wybrać do której zmiennej przypisać podaną wartość? Zdecydowano, że podawane wartości będą przypisywane kolejnym zmiennym rozpoczynając od lewej strony. Podsumowując, argumenty domyślne służą czasem nieocenioną pomocą nie należy ich jednak nadużywać :). PRZECIĄŻANIE NAZW FUNKCJI Dyskusje o tym która nazwa jest poprawna przeciążanie czy też przeładowanie (ang. overload, overloaded) nie są w tej chwili dla nas istotne ważne jest natomiast aby pamiętać je obie bo w różnych książkach i opracowaniach stosowane są zamiennie (czasem niezbyt konsekwentnie :/). Właściwie odpowiednia nazwa nie ma specjalnego znaczenia jeśli po prostu będziemy wiedzieli o co chodzi, ja zdecydowałem na ułożenie nazw w kolejności alfabetycznej i padło na przeciążanie i tej nazwy będziemy się trzymali. Przejdźmy do konkretów, co to jest przeciążanie i co realnego nam ono daje. Wcześniej wspomniane zostały argumenty domyślne funkcji które to dobrze sprawdzają się w wielu sytuacjach, co jednak jeśli chcemy aby nasza funkcja dodatkowo wykonywała określone działania w zależności od ilości dostarczonych jej argumentów? Nie jest to proste bo często należałoby dopisać dosyć skomplikowaną obsługę tego faktu wewnątrz samej funkcji. Dużo łatwiejszym rozwiązaniem jest właśnie przeciążenie nazwy funkcji: W powyższym przykładzie mamy zadeklarowane i zdefiniowane TRZY funkcje o tej samej nazwie :) jak to jest możliwe? Sprawa właściwie jest dosyć prosta, kompilator nie rozróżnia funkcji po nazwie, nazwy są tworzone PRZEZ piszącego i DLA piszącego program, kompilatorowi jest zupełnie obojętne czy nasza funkcja będzie nazwana SuperWymiataczNUmerJeden() czy też sdfgergh() dla kompilatora istotne są parametry funkcji to po nich w tym przypadku orientuje się czego od niego oczekujemy. Oczywiście nie jest możliwe utworzenie dwóch funkcji o identycznej nazwie i identycznych parametrach gdyż kompilator zasygnalizuje nam błąd - po prostu nie będzie wiedział której z dostępnych funkcji ma użyć w danym miejscu. W naszym przykładzie nie było tego problemu gdyż każda funkcja miała inny zestaw parametrów więc każda została potraktowana jako coś innego niezależnego. Przeciążanie nazw funkcji jest szczególnie przydatne w pracy z klasami a dokładniej ich konstruktorem, to właśnie konstruktor bardzo często jest funkcją której nazwa jest wielokrotnie przeciążana. PRZECIĄŻANIE OPERATORÓW Przeciążanie operatorów jest odrobinę bardziej skomplikowane ale niewątpliwie jest przydatne przy pracy z klasami. Przykładowa sytuacja: Mamy utworzone 2 obiekty klasy proba o nazwach nr1 i nr2, każdy z obiektów ma jedną zmienną prywatną o nazwie i_liczba która to zmienna jest inicjowana w momencie tworzenia dzięki konstruktorowi wartością (tu dla nr1 jest to 20 a dla nr2 liczba 12). Teraz wyobraźmy sobie sytuację gdy chcemy dodać z obiektu nr2 zawartość zmiennej i_liczba do zmiennej i_liczba obiektu nr1. Trzeba by dopisać do klasy przynajmniej dwie dodatkowe funkcje, jedna która odczyta nam zawartość zmiennej oraz druga która doda nam przesłany parametr do zmiennej (jako ćwiczenie proponuję przed dalszą lekturą napisać sobie wspomniane funkcje). Mam nadzieję, że ww funkcje są już napisane i działają poprawnie, teraz poznamy nieco inny sposób rozwiązania naszego problemu przy okazji na konkretnym przykładzie zapoznamy się z przeciążaniem operatorów - w tym przypadku operatora "+". Jako public w klasie pojawiła nam się nowa funkcja: proba operator +(proba); Funkcja ta "zwraca jako rezultat" swojego działania obiekt klasy proba a jako parametr wywołania przyjmuje także obiekt klasy proba. Oznacza to tyle, że "coś tam" będzie odczytane z dostarczonego obiektu i przekazane do obiektu zwracanego. Definicję funkcji piszemy jak zwykle: proba proba::operator +(proba nowa) od lewej: - typ wartości zwracanej - informacja do jakiej klasy przynależy ta funkcja - :: operator zakresu - operator + (informacja że przeładowywany będzie operator +) - to jest "nazwa" naszej funkcji - w nawiasie: typ przyjmowanego obiektu i jego nazwa chwilowa sama treść funkcji raczej nie powinna budzić wątpliwości: i_liczba += nowa.i_liczba; do zmiennej i_liczba dodaj wartość zawartą w zmiennej i_liczba obiektu nazwanego nowa wykorzystanie przeładowanego operatora + jest bardzo proste: nr1 + nr2; czyli do zmiennej i_liczba zawartej w obiekcie nr1 dodaj zawartość zmiennej i_liczba zawartej w obiekcie nr2. Dla was już pozostawiam jako ćwiczenie dopisanie wyświetlanie zawartości zmiennej i_liczba z obiektu nr1, warto zerknąć czy aby na pewno jest tam oczekiwana wartość ? :) W omówiony sposób można przeciążyć większość dostępnych operatorów (operatorami zatrzeżonymi są: "::" , "." oraz ".*" ). |
|