Niezbędnik made by Siuda
ten niezbędnik jest to zbior, pewnego rodzaju esencja najważniejszych informacji zawartych w greboszu. Obejmuje on zakres od klas po funkcje wirtualne włącznie. Przeznaczony jest glownie dla osob zaliczających kolo u Głowackiego. Nie ma tu zbędnych opisow i wytłumaczeń. Aby zrozumiec o co chodzi trzeba się podeprzeć symfonia.
Na początku powiem ze czeka was w chuj czytania i duzo nauki
Klasy nazwaklasy- tak się nazywa przykladowa klasa składnik tej klasy to - skladnik i wiadomo o co chodzi
Klasa jest to nowy typ zdefiniowany przez użytkownika tak jak np. int short float
Deklaracja klasy to nazwaklasy { cialo klasy};
Nasz własny obiekt klasy tworzymy pisząc nazwaklay abc obiekt czyli egzemplarz klasy
Możemy utworzyć typ pochodny od własnych typów np. wskaźnik nazwakasy*wsk ;
Albo referencje nazwaklasy obiekcik; nazwaklasy & przezw=obiekcik;
W ciele klasy definiuje się składniki klasy mogą to być int float itd
Aby odnieść się do tych składników możemy uzyyc : nazwaklasy.skladnik lub wskaźnik -> składnik referencja.skladnik
Składnikami klasy mogą być funkcje. Nie ma znaczenia w którym miejscu w klasie będzie i tak będzie znany w calej
Składnikiem klasy może być obiekt innej klasy
Zakresem ważności funkcji jest klasa w której się znajduje
Enkapsulacja - zawarcie w klasie składników i funkcji. Tworzony jest zwarty obiekt
W klasie funkcje mogą być spokojnie przeładowane.
Boze to dopiero początek pisania a mi się już nie chce
Jeśli składniki są private to tylko funkcje bedace składnikami klasy maja do nich dostep
Jeśli funkcje są private to tylko inne funkcje składowe tej klasy mogą je wywołać
Jeśli funkcje i składniki SA publiczne to jest do nich dostep spoza klasy
Jeśli nie zdefiniujemy dostępu to jest on domyślnie na private
Do składników private maja dostep tez klasy zaprzyjaźnione
Jeśli dostep jest protected to dostep maja klasy zaprzjaznione, i klasy pochodne
Po stworzeniu klasy nazwaklasy możemy stworzyc kilka egzemplarzy tej klasy piszac naszaklasa a,b,c,d
Trzeba powiedziec ze klasa to tylko definicja tak jak int czy float a obiekt to już konkretny „obiekt „ :P tak jak int a int b
Jeśli nie stworzymy obiektu klasy to definicja klasy nie zajmuje miejsca w pamieci
Definicja klasy nie może mieć inicjalizatora czyli składniki klasy nie mogą mieć przypisanej wartości
Funkcje składowe są w pamieci jednokrotne a składniki tyle razy ile klas bo funkcje działają identycznie a składniki są rozne
Funkcje składowe maja pelny dostep do składników swojej klasy
Wywolanie funkcji dla konkretnego składnika to nazwaklasy.nazwafunkcji(jakies argumenty);
Funkcje możemy wywołać wskaźnikiem i przez referencje nazwaklasy * wsk ; wsk =&nazwaobiektu; referencja :
Nazwaklasy & przezwisko = nazwaobiektu; przezwisko.nazwafunckcji(argumenty)
Definicja funkcji może znaleźć Się w ciele klasy albo poza nim ( tylko w klasie musimy zdefiniowac funkcje )
Poza klasa wyglada to tak : void nazwaklasy::nazwafunkcji(argumenty){cialo funkcji};
Nie ma znaczenia i zadnej roznicy gdzie jest tworzona funkcja
Jeśli jednak umieścimy w ciele klasy to będzie funkcja traktowana jako inline
Jeśli chcemy aby funkcja umieszczona poza klasa była inline musimy napisac przed nazwa funkcji inline void
W funkcji bez naszej wiedzy przesylany jest wskaźnik do konkretnego obiektu
Moglibyśmy sami to zrobic ale jeśli tego nie zrobimy to kompilator sam to zrobi i będzie fajnie bo mniej pracy dla nas
A i taki wskaźnik ma typ staly czyli cosnt i nie wolno nim poruszac
skladniki bedace w klasie zasłaniają skladniki o takiej samej nazwie ale globalne lub lokalne staja się one niedostępne
w klasie tez możemy sobie stworzyc zakres lokalny i skladniki z tego zakresu zasłonią skladniki klasy --- takie jaja
nazwa zaslania inna nazwe bez znaczenia czy to jest funkcja czy zmienna
kuzwa ze tez nikt się nie pokusil o stworzenie niezbędnika tylko ja teraz musze czas marnowac no… szczyt lenistwa ludzie !
jeśli nazwa funkcji jest przeslonieta przez zmienna to kompilator zaprotestuje jak pracownicy PKP
jeśli jednak chcemy bardzo ja wywołać to musimy uzyc :: w sposób następujący nazwaklasy::nazwafunkcji
funkcja skladowa ma zakres klasy a nieskladowa zakres pliku
jeśli funkcja globalna jest zaslonieta przez funkcje która jest przeladowana to i tak będzie brane pod uwage przeladowanie
przez domniemanie zaklada się ze obiekt jest przesylany do funkcji przez wartość
inline oznacza ze wszedzie gdzie jest wywolywana kompilator wstawi tresc funkcji
Nie dziala to Gdy funkcje jest definiowana poza klasa
Wysylanie przez wartość to znaczy ze funkcja tworzy na stosie ( do spalenia ) kopie danego obiektu i nadaje nazwe inna
Wysylanie przez wartość wydluza prace trwania programu i spowalnia go
Wysylanie przez referencje to stosowanie konkretnego przezwiska czyli funkcja ma dostep do oryginalu i nie kopiuje go
Jedyna roznica miedzy definiowaniem przez referencje i przez wartość to znak ameprsant czyli &
Przykladowa funkcja przez referencje nazwafunkcji( nazwaklasy & przezwisko ) proste jak funkcja liniowa
Co za tym idzie przy referencji funkcja może dokonywac zmian na oryginale
Konstruktor nazywa się tak samo jak klasa
Jest on automatycznie wywoływany gdy tworzymy nowy obiekt klasy
Konstruktor możemy definiowac wewnątrz lub poza cialem klasy
Wspomne ale tylko dla wlasnej informacji ze znaczek :: mowi nam ze dana funkcja odnosi się do danej klasy
Jak to nie rozumiesz przeciez to proste !
Dwa konstruktory możemy definiowac tak jak inty po przecinku np. nazwaklasy konstr1( argumenty ), kontr2( argumenty)
Naturalnie konstruktory mogą mieć przeladowane nazwy, to który zostanie wywolany wynika z kolejności i typow argumento
Konstruktor jest wywoływany raz. Tylko wtedy gdy obiekt jest powoływany do zycia
Konstruktor to nie konstruktor. To znaczy ze nie konstruuje tylko nadaje wartość poczatkowa
Przeciwieństwem konstruktora jest destruktor. Wywoływany jest gdy obiekt klasy ma być zlikwidowany
Destruktor to funkcja skladowa klasy i definiuje się ~nazwaklasy ()
Destruktory i konstruktory nie maja określonego typu zwracania !
Nie wiem czy mowilem już ale zmienna globalna jest dostepna wszystkim i w calym programie
Dana statyczna jest definiowana jednokrotnie ijest dostepna dla wszystkich obiektow klasy w której jest zdefiniowana
Definiujemy ja piszac przed deklaracja skldnika slowo static for example static int składnik;
Deklaracja takiego składnika to nie jego definicja. Musimy go zdefiniowac tak aby był globalny i możemy mu nadac wartość
Składnik statyczny może być typu private
Mamy 3 sposoby odniesienia się do składnika static nazwaklasy::składnik , obiekt.skladnik , nazwaklasy*wsk ; wsk->składnik
Jeśli nie zainicjalizujemy ( trudne slowo ) składnika statycznego to jest on domyślnie z wartością 0
Jeśli funkcja pracuje tylko na statycznych składnikach to można ja zadeklarowac jako statyczna
Funkcje statyczna można wywołać nie tylko na rzecz obiektu ale także klasy
Wewnątrz funkcji składowej nie możemy się odnosic do wskaźnika his oraz niestatecznego składnika klasy
funkcje static możemy wywołać nawet wtedy gry nie istnieje żaden obiekt klasy
mam nadzieje ze podpierasz to co tu pisze czytaniem grebosza
ostatecznie funkcja static może się odwoływać do niestatecznych składników poprzez obiekt.nazwaskladnika albo wskaznikie
wazne ze za pomoca funkcji static możemy się odwołać do elementu private klasy
skladniki z dopiskiem const nie mogą być zmieniane. Maja jedna ustalona wartość.
Obiekt const mogą wywołać tylko funkcje które go nie zmienia czyli cosnt
Jak znow nie rozumiesz…. Doczytaj z grebosza a zrozumiesz…. LENIU !
Funkcja const możemy wywołać skladniki niecosnt
Funkcja volatile sięga zawsze po prawdziwe dane składowe bez względu na etap programu który się wykonuje cofnie się na pocza
Rozniez ona pracuje na składnikach niecosnt i ma się dobrze
Funkcja może być zarówno const jak i volatile jednoczesnie
Konstruktory nie mogą mieć takich przydomkow a mimo to pozwalaja pracowac na takich obiektach ( łaskawcy )
Funkcje składowe aby moc być przeladowanymi musza się roznic lista argumentow. Nie ma znaczenia czy będzie cosnt czy Volat
Jeśli przeladujemy funkcje const to kompilator będzie próbował dopasowac tylko z tych które maja const reszte odrzuci
To samo się tyczy tych z volatile
Funkcja zaprzyjazniona to taka która mimo iż nie jest składnikiem klasy ma dostep do wszystkich nawet prywatnych sklad klasy
Wazne jest to ze to klasa musi mowic ze się przyjazni z jakas funkcja. Wiec w klasie głównej piszemy słówko friend
Powtorze ze jeśli jakies skladniki klasy SA prywatne to tylko funkcje tej klasy maja do nich dostep.
Funkcja może być przyjacielem wiecej niż jednej klasy
Funkcja zaprzyjazniona może wykonywac konwersje na argumentach jej wywolania zdefiniowane przez nas
Przy deklaracji przyjazni może być tylko deklaracja klasy
Funkcja zaprzyjazniona nie ma wskaźnika this bo nie jest składnikiem klasy w takich sytuacjach albo . albo ->
Przyjacielem się jest albo nie jest wiec nie ma znaczenia w którym miejscu klasy zdefiniujemy sobie frienda
Jeśli w klasie będzie cala definicja funkcji zaprzyjaźnionej to jest to funkcja inline, jest przyjacielem
W przypadku przeladowania przyjacielem jest funkcja która odpowiada liscie argumentow z deklaracji przyjazni
Funkcja zaprzyjazniona może być funkcja skladowa innej klasy i ma dostep wtedy do obu klas
Funkcja zaprzyjazniona nie zawiera wskaźnika this do obiektow klas zaprzyjaźnionych jednak do swojej wlasnej tak
Możemy deklarowac zaprzyjaźnienia z klasami. Wystarczy napisac friend nazwaklasy nazwaobiektu
Przyjazn jest jednostronna i klasa która jest przyjacielem nie deklaruje żeby ta druga mogla w niej grzebac
Deklaracja funkcji zaprzyjaźnionych jest możliwa tylko względem istniejących już funkcji. Tzn musza być zdefiniowane
Czyli nie ma możliwości przyjazni funkcji klasy a z klasa b i jednoczesnie sytuacji odwrotnej.
Jedyny sposób to deklaracja przyjazni calej klasy. Tam ma racje bytu definicja zapowiadajaca
Przyjazn Nie jest przechodnia tzn przyjaciel mojego przyjaciela to nie mój przyjaciel
Wazna uwaga. Funkcja jest zaprzyjazniona z klasa a nie z obiektem. To znaczy ze ma dostep do wszystkich obiektow
Przyjazn nie jest dziedziczona
Struktury:
Struktura to klasa w której przez domniemanie wszystkie składniki są publiczne
Definiujemy przez napisanie struci nazwastructu
Unie
Unia służy do przechowywania w pamięci jednego obiektu.
Rozmiar Uni jest taki jak rozmiar jej największego składnika
Odnoszenie się do składnika obdyba się za pomoca kropki tzn nazwaibiektu.naswaskladnika
Jeśli mamy zapisana w unii np. liczbe 4 i zapiszemy nastepnie w niej np. litere d to liczba jest usuwana na rzecz litery
Jak wczytujemy do uni dany typ to tez taki musimy z niej odczytac
Oczywiście tu tak jak w strukturze domniemanie jest public wszystko
Tak jak klasach i strukturach możemy używać slowa public i private
Unia nie może być dziedziczona
Składnikiem unii nie może zostac obiekt klasy która ma konstruktor lub destruktor
Powiadam Ci ze to 3 strona gesto zapisanego tekstu a jest jeszcze ich 270 w książce:p do tej pory zapisałem ok. 60 str z ksiazki
Składnikiem unii nie może zostac obiekt klasy która ma operator przypisania = zdefiniowany przez nas
Unia nie może mieć funkcji wirtualnej
Unie inicjalizujemy piszac union nazwa uniona :p
Do składników unii która nie ma nazwy odnosimy się piszac wprost składnik=cos
Jak definiujemy w takiej unii sklanik aaa to nigdzie indziej takiego składnika globalnego być nie może
Taka unia nie może mieć składnika private i tez nie może mieć funkcji składowej
Unia która nie ma nazwy typu ale ma obiekt lub skalnik wskazujący na nia nie jest już unia anonimowa
Pole bitowe to typ skalnika klasy na którym jest przechowywana informacja na danej ilości bitow
Pole bitowe może mieć wszystkie typy i zapisujemy go tak typ nazwapola : ilość zajmowanego miejsca
Dane z Pol bitowych układane SA wedlug kolejności implementacji
Do składników dostajemy się przez nazwaklasy.skladnik
Nie można na pole bitowe pokazac wskaźnikiem i nie może ono mieć referencji
Konstruktor sam nie przydziela sobie pamieci na obiekt on ja inicjalizuje
Jeśli klasa ma odpowiedni konstruktor to jest on uruchamiany przy każdym definiowaniu obiektu
Konstruktor może być przeladowany
Nie zwraca zadnej danej i nie ma zdefiniowanego typu zwracania
Konstruktor może być wywolany aby stworzyc obiekt const lub volatile ale sam taki być nie może i być static i virtual nie może
Konstruktor ma nazwe taka jak klasa
Konstruktor jest uruchamiany automatycznie gdy napotka definicje obiektu
Konstruktory globalnych i sttycznych obiektow ruszaja zanim Się main zacznie
Operator New. Tworzymy nim nowe obiekty które zyja do momentu Az nie napotkaja delete
Obiekt taki jjest dostępny tylko wtedy gdy istnieje przynajmniej jeden wskaźnik pokazujący na niego
Zadaniem konstruktora jest utworzyc obiekt nazwaklasy(argumenty)
Konstruktor jest wywoływany gdy tworzymy obiekty chwilowe i gdy powstaje obiekt klasy zawierający w sobie obiekt innej klas
Destruktor jest wywoływany gdy jest likwidowany obiekt
Klasa nie musi mieć obowiązkowo destruktora, destruktor nie likwiduje obiektu i nie zwlnia pamieci która obiekt zjmowal
Przydaje się wtedy gdy trzeba posprzątać
Destruktor nie zwraca zadnej wartości i nie może być przeladowany
Destruktor jest automatycznie wywoływany gdy obiekt chwilowy lub automatyczny wychodzi z zkaresu swojej ważności
Obiekt klasy majacej destruktor nie może być składnikiem unii
Destruktor nie ma przydomkow cons i volat… ale może pracowac na obiektach swojej klasy z czyms takim
Destruktor można wywołać jawnie nazwaobiektu.~nazwaklasy()
Bo destruktor to nazwaklazy poprzedzona wezykiem
Z wnętrza klasy w której dziala destruktor możemy go wywołać piszac this ->~nazwaklasy()
Konstruktor domniemany to taki który możemy wywolac bez argumentow
Jeśli klasa nie ma konstruktora to go sobie sama wywola i będzie on domniemany
Konstruktor wyglada tez tak nazwaklasy::nazwaklay (argumenty) : lista inicjalizacyjna {}
Konstruktor może być w klasie zdeklarowany a poza nia dopiero zdefiniowany
Lista inicjalizacyjna to lista prac które ma konstruktor wykonac
Jeśli na liscie jest napis costam(f) to oznacza to składnik costam zainincjalizowac watroscia argumentu f
Czyli składnikowi const możemy nadac wartość tylko przez liste inicjalizacyjna
Lista inicjalizacyjna nie może zainicjalizowac składnika static
Składnik static jest staly dla wszystkich obiektow klasy w której powstal
Obiekt jakiejs klasy ktory jest składnikiem innej klasy może być inicjalizowny tylko w liscie inicjalizacyjnej
Jeśli obiekt składówy nie posiada konstruktora to się go nie umieszcza na liscie inicjalizacyjnej
Jeśli klasa ma konstruktor domniemany to można go na liscie pominąć
Jeśli klasa ma kilka konstruktorow i wszystkie z argumentami trzeba określić który konstruktor uruchomic
Najpierw do pracy rusza destruktor klasy zawierającej obiekty a dopiero potem destruktor obiektow składowych
Pierwsze 100 stron zrobione
Obiekty składowe w klasie maja pierszenstwo z konstruktorami a dopiero po nich wskakuje konstruktor klasy
Klasa która nie ma publicznych konstruktorow jest nazywana prywatna
Konstruktory mogą być w klasie jedne prywatne a drugie publiczne
Jeśli konstruktor jest protected to zachowuje się jak private tylko klasy pochodne tez maja do niego dostep
Kuzwa ale mi się nie chce tego pisac…
Konstruktor kopiujący kopiuje już instniejacy obiekt nazwaklasy::nazwaklasy(nazwaklasy &)
Konstruktor kopiujący nie jest obowiązkowy jeśli sami go nie napiszemy to sam się skubany wygeneruje
Konstruktor kopiujący dziala na zasadzie inicjalizacji
Niejawne wywolanie konstruktora nastepuje w sytuacji :podczas przesylania argumentow do funkcji jeśli argumentem funkcji jest obiekt klasy X a przeslanie odbywa Się przez wartość, druga sytuacja to podczas gdy funkcja jako rezultat swoiej pracy zwraca obiekt klasy X przez wartość
To ze konstruktor przyjmuje jako argument referencje klasy daje mu możliwość pracowania na oryginale i może go modyfikowac
Konstruktorowi kopiującemu nie można ufac bo to wredna bestia jest i może zmienic wartość poczatkowa argumentu
Obiekty const nie mogą być wykorzystane aby robic z nich kopie
Jeśli chcemy zagwarantowac ze konstruktor kopiujący nic nie zmieni piszemy nazwaklasy::nazwaklasy( const nazwaklasy&kopi)
Boze jak to wytłumaczyć …. Jeśli nasza klasa ma skladniki bedace obiektami innych klas to sposób ten możemy zastosowac tylko wtedy gry konstruktory wewnętrznych obiektow można wywołać dla obiektow typu const
Jeśli sami nie napiszemy konstruktora kopiującego to komputer sam go wygeneruje i będzie składnik po składniku kopiowal
Do indentycznych kopii wystarczy nam automatyczny konstruktor wiec nie ma sensu się piedrolic z pisaniem tego samemu
Zrob przerwe i piwa się napij
Możemy sobie stworzyc tablice obiektow naszej klasy robimy to tak nazwaklasy nazwatablicy [ilość kratek]
Możemy się odnosic do elementow tych tablic za pomoca wskaźników i kropki
Pamiętaj człowieku mlody ze jak masz 8 element tablicy to jest on tak naprawde 9
Agregat to skupisko danych
Takim skupiskiem jest np. tablica obiektow klasy k lub obiekt klasy k gdy klasa k nie ma składników danych prywatnych lub zastrzezonych , nie ma konstruktorow ani klas podstawowych i funkcji wirtualnych
Agregat można inicjalizowac za pomoca listy inicjalizacyjnej
Sama tablica jest agregatem
W liscie inicjalizacyjnej możemy zamieszczac mniej argumentow niż dany obiekt wymaga.
Gdy czegos nie wypelnimy danymi wtedy przyjmowana jest wartość 0 lub null dla strongow
Jeśli tablica lub obiekt nie jest agregatem to nie można ich inicjalizowaz za pomoca listy inicjalizacyjnej
Lista inicjalizatorow lezy poza obszarem ważności kalsy wiec skladniki private nie SA obejmowane
Tablice które tworzone SA w zapisie pamieci za pomoca operatora New nie mogą mieć jawnie wpisanej inicjalizacji
Takie tablice możemy wykreowac gdy klasa nie ma konstruktora i wśród swoich konstruktorow ma kontr domniemany
Bo konstruktor domniemany zajmuje się inicjalizacja tej tablicy
Konwersje może sobie definiowac sam użytkownik
Sluzy do tego albo konstruktor klasy X przyjmujący jako jedyny argument obiekt typu A albo operator konwersji
Operator konwersji to specjalna funkcja skladowa
Konwersje mogą być wywoływane jawnie lub nie. Kompilator sam sobie może ich używać
Konstruktor przyjmujący jeden argument okresla konwersje od typu tego argumentu do tpu klasy do której sam należy
Generalnie wyskakuje konstruktor który zamienia typy i to tyle w temacie konwersji
Konstruktor wyglada tak na przykładzie funkcji zespolonej chyba nazwa klasy nazwaobiektu = nazwafunkcji( argumenty)
Typem który konwertujemy nie musi być np. int może to być tez klasa
Aby było to możliwe klasa musi udostępnić skladniki. Najlepiej przez public funkcje które dadza te skladniki ub deklaracje firiend
Funkcja konwertujaca wygląda następująco K::operator t() t-jest to typn na który chcemy konwertowac
Musimy wyposażyć w taka funkcje nasza klase
Funkcja konwertujaca nie musi być funkcja skladowa klasy. Jest w niej wskaźnik This do obiektu który ma podac konwersji
Funkcja -II—nie ma określonego typu rezultatu zwracanego i nie może być przeladowana, jest dziedziczona i może być wirtualna
Konstruktor jednoargumentowy przeksztalca nam od obcego typu na typ swojej klasy.
Funkcja konwertujaca od typu swojej klasy na typ obcy
Możemy wybrac jeden odpowiedni sposób. Oba razem wywołają blad. No chyba ze my jawnie napiszemy co ma zrobic to ok.
Wady konstruktora do konwersji : nie można zdefiniowac go do typu wbudowanego, nie można napisac go do klasy do której nie mamy dostępu, musimy mieć dostep do obu klas z których chcemy konwertowac, tu argumenty musza pasowac ten przy konstruktorze konwertującym do tego deklarowanego w konstruktorze
Jego się nie dziedziczy
Funkcje konwertujaca możemy dziedziczyc
Wszedzie tam gdzie się nie zgadzaja typy argumentow wylezie nam konwersja i zrobi porządek do tego niejawnie
Nie można stosowac konwersji 2 razy. X na Y a potem Y na Z żeby mieć X na Z tyczy to tylko niejawnych konwersji
Jeśli robimy to jawnie za każdym razem to sobie możemy walic jak chcemy
Konwersje utworzone przez nas uruchamiaja się tylko gdy nic kompilator nie może dopasowac. Pierszenstwo maja wbudowane konwersje
Gdy niejawna konwersja ma zajsc a ma dwa sposoby na zrrobienie tego będzie dupa blada i nic się nie stanie bo tak nie może być
Kompilator będzie szukal jak najkrótszej drogi do konwersji
Najpierw kompilator rozsądza sprawę dwuznaczności a dopiero potem dostępu
Przeladowanie operatorow:
Definiowanie operatora dodawanie klas typzwracany operatorX (argumenty) {cialo}
Funkcja przeladowania operatora nazywa się operatorX ( gdzie X to dowolny operator nadający się do przeladowania )
Jako co najmniej jeden z argumentow przyjmuje obiekt danej klasy
Nie mogą być przeladowane . .* :: :?
Nie można wymyślać wlasnych operatorow. Przeladowanie nadaje operatorowi dowolne znaczenie
Nie można zmieniac priorytetu operatorow
Nie możemy zmieniac argumentowości operatorow. Czyli jeśli jest jednoargumentowy to taki ma zostac
Nie możemy zmieniac stronności argumentow czyli jak mamy cos z lewej strony to tam ma zostac
Przynajmniej jeden z argumentow musi być zdefiniowany przez użytkownika
Nie mogą być argumenty domniemane. Kompilator musi dokladnie wiedziec o co chodzi
Funkcja operatorowa może być zwykla globalna albo niestateczna funkcja skladowa klasy
Operator nie musi być zaprzyjaźniony chyba ze ma on pracowac na private składnikach chyba ze jest fo funkcja skkladowa klasy
W klasach i funkcjach sa predefiniowane operatory takie jak = & , które automatycznie się tam dostosowuja
Operatorow predefiniowanych nie da się rozdefinowac, ale można je zadefiniowac na nowo
Tylko operator () może mieć wiecej niż dwa argumenty i sa one oddzielone przecinkami.
Funkcja operatorowa która jest funkcja skladowa klasy wymaga aby obiekt stojay po lewej stronie operatora był obiktem jej klasy
Operator który jest zwykla funkcja globalna - nie ma tego ograniczenia
sa 4 operatory które musza bys niestatecznymi funkcjami składowymi klasy = [] () ->
operator = jeśli go nie zdefiniujemy to kompilator stworzy metoda składnik po składniku dokladnie dwie identyczne kopir
jednak wiaze się to z problemami bo gdy na taki obiekt wskazuje wskaźnik albo ma cos z New to już kopia nie zadziala
wtedy najlepiej napisac swoja wersje operatora
jeśli znaczek = wystepuje przy inicjalizacji to do pracy rusza konstruktor kopiujący. W innych przypadkach jest to przypisanie
inicjalizacja zajmuje się konstruktor kopiujący a przypisaniem operator
operator przypisania sklada się z 2 czesci. Najpierw kasuje poprzedni obiekt a potem tworzy na nowo dla nas specjalnie
operator przypisania Może jako argument przyjmowac obiekt danj klasy przeslany przez wartość lub referencje
jeśli nie zdefiniujemy takiego operatora kompilator sam go stworzy
jednak jeśli klasa ma składnik const to operator nie będzie wygenerowany
tak samo jest w przypadku referencji
bo jak wiemy referencje czyli przezwisko się tylko inicjalizuje a potem już nie można przerzucic przezwiska na inny obiekt
jeśli jakas klasa zawiera inna klase a w niej jest zawarty private operator przypisania to tez nie będzie generowany
przypominam jeżeli operator jest funkcja skladowa to może być dziedziczony. Nie dotyczy to =
jeśli chcemy przeładować [] to funkcja operatorowa musi być niestatyczyna funkcja skladowa klasy
ten operator może stac po obi stronach przypisania np. tasb[]=tac[]
tak może być tylko gdy po lewej stronie stoi tylko wyrażenie onzaczajace obiekt
chcąc napisac funkcje operatorowa [] tak aby operator mogl stac po obu stronach znaku przypisania musimy zadeklarowac ze funkcja zwraca referencje do tego czemu mamy przypisywac
jeśli chcemy aby miał on podobne zastosowanie jak normalnie to musi jako rezultat zwracac referencje do obiektu będącego pojedynczym wybranym elementem tablicy
możemy przeładować operator nasz zastapiony np. () jego można przeładować
jeśli chodzi o przeladowanie operatora -> to w książce tam jakis kosmos jest a ja kosmosu tu nie będę przenosil bo miejca brak
wiec z laski swojej weź książkę w lapy i to sam przeczytaj
operatory wczeniej wymienione i omawiane nie ma znaczenia co będą zwracac
w przpadku operatora New i delete ma to duze znaczenie
operator New sluzy do rezerwacji pamieci
jeśli nie utworzymy definicji operatora New to kompilator podstawi standardowa
operator New jest funkcja skladowa statyczna. Jest wywoływany na rzecz konkretnego obiektu
nowa funkcja operator New () musi zwracat typ void a pierwszy argument musi być typu size_t
jeśli funkcja jest statyczna to nie ma ukrytego argumentu this
zatem pierwszy argument to faktycznie pierwszy z listy argumentow
jeśli nie napiszemy slowa static to kompilator i tak sam za nas to napisze
aby klasa mogla mieć obiekt tworzone w pamieci operatorem New to powinna mieć konstruktor domniemany
operator delete sluzy do oddawania obszarow zarezerwowanej pamieci
funkcja operator delete jest sratyczna funkcja skladowa klasy. Tu tez jeśli zapomnimy o static to kompilator sam dopisze
musi mieć ona pierwszy argument typu void* i ma zwracac typ void
jeśli uzyjemy operatora :: to dzieki niemu mamy dostep do zasłoniętych nazw globalnych'
aby napisac funkcje operatorowa dla ++ musimy uzyc go z 2 argumentami
operatory możemy przeładować na dwa sposoby albo jako funkcje skladowa albo jako globalna
jeśli operator wykonuje jakas prace na argumencie tzn zmienia go to powinna być to funkcja skladowa
a jeśli nie zmienia nic to może być i lepiej jak będzie globalny
jeśli chcemy aby w obi argumentach mogly zajsc konwersje to stosujemy sobie operator jako funkcje globalna
a jeśli nie chcemy konwersji to proszę Cie rob to jako funkcje skladowa
funkcja operatorowa może być globalna i nie musi być zaprzyjazniona z klasami żeby z nimi współpracować
dziedziczenie
jak się to zapisuje class nazwanowejklasy : nazwastarejklasy {} i już po bolu
w klasie pochodnej czyli dziedziczonej możemy zdefioniowac dodatkowe dane i funkcje składowe, zdefiniowac składnik który istnieje już w klasie podstawowej.
Dzieki dziedziczeniu klasa pochodna posiada wszystkie skladniki klasy podstawowej. Jednak skladniki te nie maja jednakowego zaresu. Skladniki odziedziczone maja zakres klasy podstawowej a na to naklada się zakres klasy pochodnej
Skladniki o tej samej nazwie zostaja zasłonięte. Czyli tez z podstawowej jest zasłaniany przez pochodna
Jeśli chcemy się odwołać do funkcji zasłoniętej to musimy uzyc ::
Dziedziczenie odbywa się na klasach a nie konkretnych obiektach. WAZNE
Skladniki prywatne klasy podstawowej nie sa dostępne dla kalsy pochodnej
Ale jeśli posiada podstawowa jakies nieprywatne funkcje to one z poziomu pochodnej maja dostep do tych private składników
Do sklanikow public i protected mamy swobodny dostep
Sami możemy zadecydowac jaki dostep chcemy mieć do skladnkow dziedziczonych. Jednak nie możemy go mieć innego niż w klasie podstawowej.
Domniemanie jest klasa pochodna dziedziczona jako private.
Nie dziedziczymy konstruktorow, destruktorow, operatorow przypisania
Dziedziczenie może być kilkupokoleniowe
Pierszenstwo przy uruchamianiu konstruktorow ma konstruktor klasy podstawowej
Kolejność jest taka. Najpierw starszy potem gosc potem ja
Na liscie inicjalizacyjnej możemy wywolc konstruktor klasy podstawowej
W przypadku braku konstruktora klasy podstawowej na liscie inicjalizcyjnej automatycznie uruchamiany jest domniemany kostr
Możemy pominc na liscie inicjlizcyjnej wydolnie konstruktor bezpośredniej klsy podstawowej wtedy gdy podstawowa nie m konstruktorow albo ma a w srod nich konstruktor domniemany
Destrukcja obiektow nastepuje w odwrotnej kolejności
Klasa pochodna nie definiuje swojego operatora przypisania to kompilator robi to metod składnik po sklaniku
Gdy klasa ma jakis składnik const lub z referencja to operator przpisania nie będzie wygenerowany
Jeśli klasa nie ma swojego konstruktora kopiującego to kompilator napisze go z metoda składnik po składniku
Konstruktor kopiujący nie jest generowany gdy skldniki klsy lub klsa podstawow m konstruktor kopiujący
Aby moc się posłużyć obiektem wzorcowym const wszyscy współpracownicy konstruktora kopiuj, lub operatora przyp musza gwrntowc ze dadza mu nietykalność
Klasa może się wywodzic od wiecej niż jednej klsy
Na liscie inicjalizującej musi być klasa już znna. Nie wystarczy tylko deklaruj zapowiadajaca
Pamiętaj najpierw sprawdza się jednoznaczność a dopiero potem wewntualny dostep
Bliższe pokrewieństwo powoduje ze nie ma problemu jeśli klasy nadrzedne maja skladniki takiej samej nzwy.
Wskznik do obiektu klsy pochodnej może być niejawnie przekształcony na wskaźnik dostępnej jednoznacznie klasy podstawowej
To samo się tyczy referencji wiec tlko w zdaniu zamien wskznik na referencje
Konwersje standardowe wskaźnika do obiektu klasy pochodnej na wskaźnik obiektu publicznej klasy podstawowej mogą zajsc w sytuacjach typowych dla innych konwersji standardowych : przy przesylaniu rgumentow do funkcji
Przy zwracaniu przez funkcje rezultatu będącego referencja lub wksznikiem , przy przeladowanych operatorach i wyrażeniach inicjalizujących
Obiekty klas pochodnych mogą być traktowane jako obiekty swych klas podstawowych wtedy tylko gdy pracujemy na ich addresach. Wskaźnik zwieta zapisany adres adresem swego rodzaju jest tez referencja
Wskaźnik do klsy pochodnej będzie obsługiwany przez wskaźnik klasy podstawowej
Ale już wskznik do wskaźnika -II—już nie
Do funkcji spodziewjacej się adresu tablicy obiektow klasy podstaw nie można wyslc adresu tablicy obiektow klasy pochodnej
Funkcje wirtualne ! ostatni kuzwa temat i ide spac
Funkcja oznaczon jko wirtualna może ale nie musi być realizowana w klsach pochodnych jeszcze raz lepiej dokładniej
Generalnie chodzi o to żeby kompilator działał inteligentniej niż w zwykłym przypadku
Wydolnie funkcji wirtualnej jest polimorficzne bo istnieje wiele możliwości wywolania
Przez to ze funkcja jest wirtualna to obiekt jest wiekszy, podejmowanie decyzji tez zabiera dodatkowy czas
O tym który typ funkcji wywołać decyduje to na co wskazuje wskaźnik :P
Caly ten mechanizm jest stosowany niejawnie
Wirtualna może być tylko funkcja skladowa
Globalne funkcje się nie dziedzicza
Funkcja wirtualna w klasie podstawowej jest public a w pochodnej jest protected albo private
Funkcja wirtualna nie może być typem static, może być przyjacielem
Wczesne wiazanie to zadecydowanie o wszystkim z poziomu kompilacji
Pozne wiazanie to wiazanie na etapie wykonania
Funkcja wirtualna może być inline
Wtedy gdy mamy mieć polimorfizm to nie będzie inline
Funkcje wirtualne maja wszystkie te sam nazwe i te sme argumenty
Przeladowane funkcje to wczesne wiazanie
Klasa abstrakcyjna to klasa ktoraa nie reprezentuje zadnego konkretnego obiektu.
Funkcja czysto wirtualna w tej wersji funkcji nigdy się nie wykona
Jeśli klasa ma w sobie przynajmniej jedna funkcje czysto wirtualna wowczs nie da się zdefiniowac zdanego obiektu klasy. Klasa jest wtedy abstrakcyjna
Jeśli klasa deklaruje jedna ze swoich funkcji jako wirtualna to destruktor tez dajemy jako virtual
KONIEC