Struktury.

Slides:



Advertisements
Podobne prezentacje
Tablice 1. Deklaracja tablicy
Advertisements

C++ wykład 2 ( ) Klasy i obiekty.
C++ wykład 4 ( ) Przeciążanie operatorów.
Język C/C++ Funkcje.
Programowanie obiektowe
Programowanie obiektowe PO PO - LAB 2 Wojciech Pieprzyca.
Programowanie obiektowe
Programowanie obiektowe PO PO - LAB 4 Wojciech Pieprzyca.
Programowanie obiektowe
Wzorce.
Prowadzący: mgr inż. Elżbieta Majka
Static, const, volatile.
Dziedziczenie. Po co nam dziedziczenie? class osoba { char * imie, char * imie, * nazwisko; * nazwisko;public: void wypisz_imie(); void wypisz_imie();
PROGRAMOWANIE STRUKTURALNE
OOPC++ - wstêp, klasy1 Klasy Do struktury można dołączyć operacje działające na jej polach. struct date { int day, month, year; void set (int d, int m,
ODE Triggery. Wstęp n Triggery są trójką zdarzenie-warunek-akcja (event-condition- action). n Zdarzenia mogą być proste lub złożone, co zostanie omówione.
Wskaźniki. Definiowanie wskaźników Wskaźnik może wskazywać na obiekt dowolnego typu. int * w; char * Wsk_Znak; float * Wskaz_Real; Przykłady: Wskaźnik.
Tablice.
C++ wykład 2 ( ) Klasy i obiekty.
Zasady zaliczenia Warunki uzyskania zaliczenia:
Wykład 1: Wskaźniki Podstawy programowania Programowanie w C
Podstawy programowania PP – WYK3 Wojciech Pieprzyca.
Podstawy programowania
Podstawy programowania PP – LAB4 Wojciech Pieprzyca.
Polsko – Japońska Wyższa Szkoła Technik Komputerowych
Podstawy programowania
Podstawy programowania II
Podstawy informatyki 2013/2014
Podstawy informatyki 2013/2014 Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi.
Wskaźnik może wskazywać na obiekt dowolnego typu. int * w; char * Wsk_Znak; float * Wskaz_Float; Przykład: Wskaźnik przechowuje adres obiektu wskazanego.
struct nazwa { lista składników }; Dostęp do składowych struktury Nazwa_Zmniennej_Strukturalnej. Nazwa_Składnika.
Podstawy programowania II
T: Różnice pomiędzy programowaniem strukturalnym a obiektowym
Podstawy programowania
Programowanie obiektowe III rok EiT
Jerzy F. Kotowski1 Informatyka I Wykład 14 DEKLARATORY.
Programowanie obiektowe III rok EiT
WPROWADZENIE W ŚWIAT OBIEKTÓW
Andrzej Repak Nr albumu
Java – coś na temat Klas Piotr Rosik
Dziedziczenie Maciek Mięczakowski
Inicjalizacja i sprzątanie
Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21 Dariusz Wardowski.
Programowanie obiektowe Wykład 6 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/14 Dariusz Wardowski.
Podstawy informatyki 2013/2014
Przekazywanie parametrów do funkcji oraz zmienne globalne i lokalne
Programowanie obiektowe 2013/2014
Prasek Aneta, Skiba Katarzyna. Funkcje stałe const to takie funkcje, które nie mogą modyfikować stanu obiektu. Oznacza to, że funkcja stała nie może zmieniać.
Kurs języka C++ – wykład 3 ( )
Kurs języka C++ – wykład 9 ( )
Programowanie w języku C++
Treści multimedialne - kodowanie, przetwarzanie, prezentacja Odtwarzanie treści multimedialnych Andrzej Majkowski informatyka +
Programowanie strukturalne i obiektowe C++
Programowanie strukturalne i obiektowe C++
Zmienne i typy danych w C#
Kurs języka C++ – wykład 4 ( )
Modele pamięci Tiny - mikroskopijny do 64 K zmienne inicjalizowane kod programu zmienne nie inicjalizowane HEAP (sterta) obszar wolny STACK (stos) Model.
K URS JĘZYKA C++ – WYKŁAD 2 ( ) Klasy i obiekty.
Klasy ( uzupełnienie ). Definicja klasy Klasa jest zbiorem logicznie powiązanych danych i funkcji, przeznaczonych do realizacji konkretnego zadania; Zamknięcie.
Programowanie obiektowe Wykład 9 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/15 Dariusz Wardowski.
Przeładowanie funkcji. Dotychczas wiedzieliśmy, że: w danym zakresie ważności może być tylko jedna funkcja o danej nazwie. Kompilator języka C++ daje.
Dziedziczenie wielobazowe. dana klasa może mieć kilka bezpośrednich klas bazowych: dana klasa może mieć kilka bezpośrednich klas bazowych: kolorpołożenie.
Dziedziczenie Wykład 7 Dziedziczenie sekwencyjne
Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi i Pawła Jerzego Matuszyka Podstawy.
Podstawy informatyki Struktury Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi.
K URS JĘZYKA C++ – WYKŁAD 3 ( ) Przenoszenie Składowe statyczne Funkcje wbudowane Argumenty domyślne.
Kurs języka C++ – wykład 3 ( )
Klasy, pola, obiekty, metody. Modyfikatory dostępu, hermetyzacja
Programowanie Obiektowe – Wykład 2
Język C++ Typy Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi i Pawła Jerzego.
Zapis prezentacji:

Struktury

Dostęp do składowych struktury: Definicja struktury struct nazwa { // lista składników }; Dostęp do składowych struktury: Nazwa_Zmniennej_Strukturalnej . Nazwa_Składnika

Wskaźnik do struktury: Jeśli do obiektu strukturalnego odwołujemy się za pomocą wskaźnika, to dostęp do poszczególnych pól możemy uzyskać przez złożenie * i . lub operator -> ( znak - oraz znak > ): (* Wskaźnik_Obiektu ). Nazwa_Składnika * Wskaźnik_Obiektu . Nazwa_Składnika Wskaźnik_Obiektu -> Nazwa_Składnika

struct S1 { int i; }; struct S2 { int j; }; S1 x, y; S2 z; Każda definicja struktury wprowadza nowy, unikatowy typ, np.: struct S1 { int i; }; struct S2 { int j; }; Typy S1 i S2 są różnymi typami, zatem w deklaracjach: S1 x, y; S2 z; zmienne x oraz y są tego samego typu S1, natomiast x oraz z są różnych typów.

x = y; y = x; x = z; z = y; x.i = z.j; Wobec tego przypisania: są poprawne, podczas gdy: x = z; z = y; są błędne. Dopuszczalne są natomiast przypisania składowych o tych samych typach, np.: x.i = z.j;

Przeładowanie funkcji

Czy masz wątpliwość o wywołanie jakiej funkcji chodzi? W jezyku C w danym zakresie ważności może być tylko jedna funkcja o danej nazwie. Kompilator języka C++ daje nam większą swobodę. Przykład: void pisz(float); void pisz(char, int, char); Czy masz wątpliwość o wywołanie jakiej funkcji chodzi? pisz(‘C’, 123, ‘F’);

Przeładowanie funkcji polega na tym, że w danym zakresie ważności jest więcej niż jedna funkcja o takiej samej nazwie. To, która z nich zostaje w danym przypadku uaktywniona zależy od typu argumentów podanych podczas wywołania. Funkcje takie mają tę samą nazwę, ale muszą się różnić liczbą lub typem argumentów. Przeładowujemy funkcję wówczas, gdy wykonuje ona analogiczną akcję na różnych zestawach obiektów.

void pisz (int y); // powtórna deklaracja void pisz (int , char); void pisz (int x); void pisz (int y); // powtórna deklaracja void pisz (int , char); void pisz (float, char, int); Powtórna deklaracja nie jest błędem. W przypadku deklaracji kompilator nie zareaguje. Zaprotestuje dopiero przy definicjach tych funkcji (patrz PROG112.CPP)

int rysuj (int); float rysuj (int); int rysuj (float, int); BŁĄD ! Przy przeładowaniu ważna jest tylko odmienność argumentów. int rysuj (float, int); int rysuj (int, float); POPRAWNIE !

void pisz (float); void pisz (int); void pisz (int, int); pisz (123, (int)45.67);  void pisz (int, int); void pisz (int, int); void pisz (int, unsigned int); poprawnie !

Przeładowanie przy argumentach domniemanych void pisz (float); void pisz (char *); void pisz (int, float = 0); pisz (5.67); // pisz (float); pisz (”2000 r.”); // pisz (char *); pisz (123); // pisz (int, float = 0); pisz (123, 5.67); // pisz (int, float); void pisz (int);

void rys (void, float, float); rys_Fv rys_Fvf rys _Ffv rys _Fvff W rzeczywistości funkcje przeładowane mają różne nazwy. Kompilator zmienia nazwy wszystkich funkcji programu. Kompilator uzupełnia nazwę funkcji dodając typ argumentów: void rys(void ); void rys (void , float); void rys (float, void ); void rys (void, float, float); rys_Fv rys_Fvf rys _Ffv rys _Fvff Zmiana nazwy funkcji dotyczy zarówno definicji i deklaracji funkcji, jak też i wywołań. Informacja o typie zwracanym nie jest doczepiana do nazwy.

Rozwinięcie tej koncepcji stanowią szablony w niektórych jezykach nazywane typami ogólnymi (generic)

Klasy

Definicja klasy: class identyfikator_typu { ciało klasy }; gdzie ciało klasy zawiera deklaracje składników klasy. class Okrag { public: int x, y, r; … };

Odwołanie się do składników obiektu: Deklaracja obiektu: Okrag Zielony; Okrag * Wskaz; Okrag & Moj = Zielony; Odwołanie się do składników obiektu: obiekt . składnik wskaźnik -> składnik referencja . składnik

void Inicjalizuj ( int x1, int y1, int r1); Przykład: Zielony . r = 100; Wskaz = & Zielony; Wskaz -> r = 100; Moj . r = 100; Składnikami klasy mogą być też funkcje. class Okrag { public: int x, y, r; void Inicjalizuj ( int x1, int y1, int r1); void Rysuj ( int x1, int y1, int r1); };

Uwagi: W ogólnym przypadku deklaracje funkcji w klasie mogą być pomieszane z deklaracjami danych. Składnik jest znany w całej definicji klasy, niezależnie od miejsca zdefiniowania składnika wewnątrz klasy. Nazwy deklarowane w klasie mają zakres ważności równy obszarowi całej klasy. W ciele klasy, jak w kapsule, zamknięte są dane oraz funkcje operujące na tych danych. Takie zamknięcie nazywamy enkapsulacją ( od ang. encapsulation). Funkcje składowe klasy mają zakres klasy.

Ukrywanie informacji: class Moj_Typ { private: int Liczba; // prywatne dane składowe float Temperatura; char Komunikat [80]; int Czy_Gotowe( ); // prywatna funkcja składowa public: float Predkosc; // publiczna dana składowa int Pomiar( ); // publiczna funkcja składowa }

Ukrywanie informacji: Są 3 etykiety, za pomocą których można określać dostęp do składników klasy: private: protected: public:

Ukrywanie informacji: Składnik private: jest dostępny tylko dla składowych danej klasy. Jeżeli zależy nam na ukryciu informacji, to wówczas składnik powinien być deklarowany jako prywatny. Składnik protected: jest dostępny tak, jak składnik private, ale dodatkowo jest dostępny dla klas wywodzących się z danej klasy. Składnik public: jest dostępny bez ograniczeń. Zwykle składnikami takimi są wybrane funkcje składowe. Za ich pomocą dokonujemy z zewnątrz operacji na danych prywatnych. Etykiety można umieszczać w dowolnej kolejności, mogą też się powtarzać. Zakłada się, że dopóki w definicji klasy nie wystąpi żadna z tych etykiet, składniki przez domniemanie mają dostęp private.

Klasa a obiekt : class Osoba { char Nazwisko[40]; int Wiek; public: void Zapamietaj (char *, int); void Pisz ( ); }; Osoba Student1, Student2, Asystent; W pamięci utworzone zostały 3 różne komplety danych składowych (Nazwisko i Wiek). Natomiast funkcje składowe są zapamiętane w pamięci tylko jednokrotnie.

Funkcje składowe : Funkcje składowe mają pełny dostęp do wszystkich składników swojej klasy, to znaczy: do danych (mogą z nich korzystać) i do innych funkcji (mogą je wywoływać). Do składnika swojej klasy funkcje odwołują się przez podanie jego nazwy . Nazwa_Obiektu . Nazwa_Funkcji_Składowej ( argumenty ); Student1 . Zapamietaj (Kowalski, 21);

Funkcje składowe : Możemy także wywołać funkcję składową dla danego obiektu, pokazując na niego wskaźnikiem lub za pomocą referencji np.: Osoba * Wsk; Wsk = &Asystent; Osoba &Belfer = Asystent; Wsk -> Zapamietaj (Kowalski, 21); Belfer. Zapamietaj (Nowak, 30);

Definiowanie funkcji składowych : Pierwszy sposób: wewnątrz definicji klasy. class Osoba { char Nazwisko [80]; // składniki prywatne int Wiek; public: // składniki publiczne void Zapamietaj (char * Napis, int Lata ) { strcpy (Nazwisko, Napis); Wiek = Lata; } void Pisz ( ) cout << Nazwisko << , lat:  << Wiek << endl; };

Drugi sposób: w definicji klasy umieszcza się tylko same deklaracje funkcji składowych, natomiast definicje są napisane poza ciałem klasy. class Osoba { char Nazwisko [80]; // składniki prywatne int Wiek; public: // składniki publiczne void Zapamietaj (char * Napis, int Lata ); void Pisz ( ); }; void Osoba::Zapamietaj (char * Napis, int Lata ) strcpy (Nazwisko, Napis); Wiek = Lata; } void Osoba::Pisz ( ) cout << Nazwisko << , lat:  << Wiek << endl;

Ponieważ funkcje znajdują się teraz poza definicją klasy, dlatego ich nazwa została uzupełniona nazwą klasy, do której mają należeć. Służy do tego operator zakresu ::. Funkcja zdefiniowana poza klasą ma dokładnie taki sam zakres, jakby była zdefiniowana wewnątrz klasy. Jednakże sposób definiowania funkcji wewnątrz, czy na zewnątrz definicji klasy stanowi różnicę dla kompilatora. Jeśli bowiem funkcję składową zdefiniowaliśmy wewnątrz definicji klasy, to kompilator uznaje, że chcemy, aby ta funkcja była typu inline.

inline int Zaokr ( float Liczba); { return (Liczba + 0.5); } Funkcja typu inline: inline int Zaokr ( float Liczba); { return (Liczba + 0.5); } Jeśli ciało funkcji składowej ma nie więcej niż dwie linijki, to funkcję tę definiujemy wewnątrz klasy. Jest ona automatycznie inline. Jeśli funkcja składowa jest dłuższa niż dwie linijki, to definiujemy ją poza definicją klasy. Nie jest ona automatycznie inline

inline void Osoba :: Pisz ( ) { // ciało funkcji } Funkcja składowa zdefiniowana poza definicją klasy może być typu inline, ale trzeba to zaznaczyć pisząc słowo inline, np.: inline void Osoba :: Pisz ( ) { // ciało funkcji }

Odwołanie się do publicznych danych składowych: class Liczby { int L1: public : float L2; void Fun ( ); }; Są tu dwie dane składowe. Składnik L1 jest prywatny (przez domniemanie). Jako prywatny może być dostępny tylko z zakresu klasy - czyli wewnątrz funkcji składowej Fun.

Składnik publiczny L2 oprócz tego, że może być dostępny w funkcji składowej Fun, dostępny jest także z zewnątrz klasy. Pracując jednak na nim z zewnątrz musimy podać, o który konkretnie obiekt chodzi, np.: Liczby Temperatura, Cisnienie; Temperatura . L2 = 18.6; Ciscienie . L2 = 1003; cout << Temperatura wynosi :  << Temperatura . L2 <<  stopni C\n; cout << Ciśnienie wynosi:  << Cisnienie . L2 <<  hPa\n;

Zasłanianie nazw (PROG57.CPP) Przesyłanie do funkcji argumentów będących obiektami Przez domniemanie zakłada się, że obiekt jest przesyłany do funkcji przez wartość. Konsekwencja: jeśli obiekt jest duży, to proces kopiowania może trwać długo. Lepszym rozwiązaniem w takim przypadku jest przesyłanie przez referencję.

void Prezentacja (Osoba &Ktos) { cout << Mam zaszczyt przedstawić Państwu,\n << Oto we własnej osobie:  ; cout << Ktos . Pisz_Dane (); }

Konstruktor : Definicję obiektu i nadanie mu wartości można załatwić w jednej instrukcji. W tym celu należy posłużyć się specjalną funkcją składową zwaną konstruktorem. Charakteryzuje się ona tym, że nazywa się tak samo jak klasa. class Numer { int Liczba; public: Numer ( int L ) { Liczba = L; } // konstruktor void Schowaj ( int L ) { Liczba = L; } int Zwracaj ( ) { return Liczba; } } ; (PROG59.CPP)

Konstruktor Klasy języka C++ wyposażone są w specjalną funkcję zwaną konstruktorem; Konstruktor jest specjalną funkcją składową, wywoływaną zawsze w chwili tworzenia obiektu danej klasy; Zadaniem konstruktora jest inicjalizacja danych składowych (pól) obiektu danej klasy, przydzielenie pamięci dla jego elementów oraz wykonanie innych czynności niezbędnych do prawidłowego utworzenia obiektu; Konstruktor nie jest obowiązkowym elementem definicji klasy.

Konstruktor Jeśli tworząc klasę nie zdefiniujesz jawnie jej konstruktora, kompilator automatycznie wygeneruje tzw. konstruktor domyślny; Rozwiązanie takie, choć dość wygodne, sprawdza się tylko dla bardzo prostych klas; W praktyce każda definicja nietrywialnej klasy będzie zawierała konstruktor; Nazwa konstruktora musi być taka sama, jak nazwa zawierającej go klasy; Konstruktor nie może zwracać żadnej wartości.

Konstruktor Klasa może posiadać więcej niż jeden konstruktor; Jest to możliwe dzięki mechanizmowi przeładowania funkcji;

Konstruktor Przypomnienie - niezainicjalizowane zmienne będą zawierały przypadkowe wartości; Reguła ta odnosi się również do klas; Dobra praktyka wymaga inicjalizowania wszystkich pól klasy; Przypomnienie - konstruktora nie można wywołać jawnie; Wywołanie konstruktora następuje w chwili tworzenia obiektu danej klasy ; W chwili powoływania obiektu wybierasz również wersję konstruktora, jeżeli dana klasa definiuje ich więcej. Ciekawostki: niepubliczny konstruktor ?

Destruktor : Przeciwieństwem konstruktora jest destruktor. Destruktor to funkcja składowa klasy. Destruktor nazywa się tak samo, jak klasa z tym, że przed nazwą ma znak ~ (tylda). Podobnie jak konstruktor - nie ma on określenia typu zwracanego. Destruktor wywoływany jest wtedy, gdy obiekt danej klasy ma być zlikwidowany.

Destruktor Destruktor jest specjalną funkcją wywoływaną w chwili likwidacji obiektu danej klasy; Destruktor jest funkcjonalnym przeciwieństwem konstruktora; Do jego zadań należy najczęściej zwalnianie zasobów wykorzystywanych przez obiekt i inne czynności natury porządkowej; Destruktor nie jest obowiązkowym elementem klasy; Destruktor możesz zdefiniować tylko raz ; Destruktor jest funkcją bezparametrową i nie zwracającą żadnej wartości; Nazwa składa się z nazwy klasy poprzedzonej znakiem ~. (p. PROG156.CPP, PROG157a.CPP)

Destruktor Destruktor jest wywoływany w chwili usuwania obiektu danej klasy; Sama likwidacja obiektu może nastąpić poprzez usunięcie go ze stosu, jeśli jest to obiekt lokalny, a operująca na nim funkcja właśnie zakończyła działanie; lub w wyniku wywołania operatora delete, jeśli obiekt został utworzony dynamicznie. W obu przypadkach wywołanie destruktora jest ostatnią czynnością obiektu przed jego unicestwieniem;

Pola Pola klasy to nic więcej, jak tylko jej lokalne zmienne; Pola klasy funkcjonują tak samo, jak pola struktury i różnią się od ostatnich wyłącznie domyślną kategorią dostępu; Wewnątrz klasy wszystkie pola są swobodnie dostępne dla wszystkich funkcji składowych; Natomiast ich widoczność na zewnątrz klasy jest uwarunkowana kwalifikatorami dostępu; Pola w sekcjach private i protected są na zewnątrz niedostępne; Pola public mogą być czytane i zapisywane spoza klasy bez ograniczeń.

Pola Rozwiązaniem problemu dostępu do pól prywatnych są specjalne funkcje klasy ustawiające i pobierające wartości tych pól; Funkcje te, zwane funkcjami udostępniającymi, deklarowane są oczywiście w sekcji publicznej; Fundamentaliści: ” wszystkie pola klas powinny być prywatne, a dostęp do nich ma byś realizowany wyłącznie za pomocą funkcji udostępniających”; Radykałowie: ” wręcz przeciwnie”; Wytyczenie granicy jest kwestią doświadczenia i zdrowego rozsądku; Jeśli nie wiesz, co robić z danym polem, umieść go w sekcji prywatnej.

Funkcje Zestaw publicznych funkcji składowych powinien być ograniczony do niezbędnego minimum zapewniającego skuteczną komunikację z obiektami i kontrolowanie ich działania; Jeśli dana funkcja składowa nie musi być widoczna na zewnątrz, powinna być zadeklarowana jako prywatna; Jeśli dana funkcja składowa nie musi być widoczna na zewnątrz, ale powinna być dostępna dla klas pochodnych, powinna być zadeklarowana jako chroniona (protected); Jeśli zależy Ci na szybkim wykonaniu funkcji, a jednocześnie jest ona niewielka, możesz zadeklarować ją jako funkcję wstawianą (inline);

Wskaźnik this Deklaracja każdej klasy zawiera ukryte pole wskaźnikowe o nazwie this; Po utworzeniu obiektu, wskaźnik this zawiera adres obiektu w pamięci; Oto klasa Punkt widziana oczami komputera: Class Punkt { private: Punkt *this; int x, y; public: Punkt (int _x, int _y); ~Punkt() .... };

Wskaźnik this Czemu służy wskaźnik this ?; Każdy obiekt danej klasy posiada własną kopię zestawu pól; Natomiast funkcje składowe są przechowywane w jednym egzemplarzu; Wskaźnik this pozwala na zidentyfikowanie właściciela danych, do których odwołuje się funkcja składowa; Jeśli chcesz uniknąć kłopotów, nigdy nie zmieniaj wartości wskaźnika this!

Dziedziczenie Dziedziczeniem nazywamy proces tworzenia nowych klas na podstawie klas już istniejących; Klasa wykorzystywana jako podstawa w procesie dziedziczenia jest klasą bazową; Klasy dziedziczące po klasie bazowej są to klasy pochodne; Klasa pochodna dziedziczy wszystkie możliwości funkcjonalne klasy bazowej, poszerzone o nowe pola i funkcje; Niemożliwe jest usunięcie jakichkolwiek elementów klasy bazowej.

Dziedziczenie Samo dziedziczenie symbolizowane jest przez znajdujący się w pierwszym wierszu deklaracji klasy dwukropek, po którym występuje nazwa klasy bazowej ; Słowo kluczowe virtual deklaruje poprzedzoną nim funkcję jako wirtualną; Jako przykład funkcji wirtualnych rozpatrz funkcje o nazwie Pokaz() w klasach Punkt i Linia_Pozioma; Ponieważ procedura narysowania na ekranie linii różni się od procedury narysowania punktu, należy w klasie Linia_Pozioma przedefiniować (przesłonić) funkcję Pokaz().

Przesłanianie Przesłanianiem nazywamy przedefiniowywanie funkcji klasy bazowej w klasach pochodnych ; Przesłanianie stosuje się w celu całkowitej zmiany działania funkcji klasy bazowej lub, znacznie częściej, jej uzupełnienia i rozszerzenia o dodatkowe operacje; Aby rozszerzyć pierwotną definicję nie musisz jej przepisywać. W nowej definicji funkcji wystarczy najpierw wywołać funkcję klasy bazowej, a następnie dopisać kod realizujący rozszerzenia; Przesłaniając funkcje klasy bazowej musisz zapewnić identyczność nagłówków funkcji; Istotne jest również aby funkcja była dostępna dla klas pochodnych.

Przesłanianie Odwołując się do funkcji klasy bazowej musisz poprzedzić ją nazwą klasy i operatorem zakresu; Użycie operatora zakresu jest konieczne tylko wtedy, gdy wywoływana funkcja jest zdefiniowana zarówno w klasie bazowej, jak i pochodnej ; Jeśli funkcja jest zdefiniowana tylko w sekcji publicznej lub chronionej klasy bazowej, a nie wchodzi w skład definicji klasy pochodnej, możesz ją wywołać bez użycia operatora zakresu.

Funkcje wirtualne Funkcją wirtualną nazywamy funkcję wywoływaną zawsze w obrębie posiadającej ją klasy; Poprzedzenie deklaracji słowem kluczowym virtual powoduje, że wszystkie odwołania do funkcji będą zawsze wykonywane w obrębie klasy, która ją zdefiniowała; Jeśli podejrzewasz, że funkcja będzie przedefiniowywana w klasach pochodnych, warto deklarować ją jako wirtualną; Jeśli przedefiniowywana funkcja jest wywoływana przez inne funkcje klasy bazowej, prawie na pewno powinieneś zadeklarować ją jako wirtualną.

Inicjalizacja obiektów Kolejnym problemem związanym z dziedziczeniem jest inicjalizacja obiektów; W chwili utworzenia obiektu klasy pochodnej należy zainicjalizować też pola klasy bazowej, a w przypadku dziedziczenia „piętrowego” - również wszystkich klas pośrednich; Najskuteczniejszym na to sposobem jest po prostu wywołanie konstruktora klasy bazowej w konstruktorze klasy pochodnej; Ponieważ nie można wywołać tego konstruktora bezpośrednio, należy wykorzystać w tym celu listę inicjalizującą; Prawidłowa inicjalizacja klasy bazowej w konstruktorze klasy pochodnej jest sprawą bardzo istotną.