Język C++

Zacznijmy od przytoczenia kilku istotnych informacji dotyczących języka C++.

Operator ++ znajdujący się w nazwie języka C++ oznacza inkrementację, czyli kolejne ulepszenia – iteracje, które zostały wprowadzone w języku C.  Pamiętajmy, że C++ jest wstecznie zgodny z językiem C.

Język C++ pozwala korzystać z mechanizmów programowania obiektowego i m.in. tym różni się od C, który jest językiem imperatywnymjęzyk imperatywnyimperatywnym oraz strukturalnymjęzyk strukturalnystrukturalnym. Jednak dowolny kod napisany w języku C powinien się skompilować za pomocą kompilatora języka w C++.

Podczas nauki języka C++ dowiadujemy się m.in., czym są funkcjefunkcjafunkcje, wskaźnikiwskaźnikwskaźniki, operatoryoperatoroperatorystrukturystruktura danychstruktury.

Już wiesz

WskaźnikPcTfIGYF8Wskaźnik (ang. pointer) to zmienna służąca do przechowywania adresu.
Operator * w językach C i C++ jest wykorzystywany w celu odwoływania się do komórki pamięci, znajdującej się pod adresem przechowywanym we wskaźniku.
Operator & w językach C i C++ służy do pobrania adresu zmiennej.

Klasy i obiekty

Zanim przejdziemy do wyjaśnienia, czym jest programowanie obiektowe, omówmy pojęcia: klasa i obiekt.

Klasa
Definicja: Klasa

Klasa jest opisem (definicją) tworzonych na jej podstawie obiektów. Składa się z pól i metod. Pola (atrybuty) przechowują wartości, które są cechami obiektu, z kolei metody pozwalają na manipulacje tymi wartościami. W języku C++ klasy definiują nowe typy danych. Klasa o nazwie Pies definiuje typ Pies, który z kolei może składać się z atrybutów: imię, rasa czy wiek.

Obiekt
Definicja: Obiekt

Obiekt jest instancją klasy, powstaje w wyniku utworzenia zmiennej typu obiektowego (danej klasy). Obiekt jest zbudowany z pól zadeklarowanych w klasie. Do zmian wartości pól możemy wykorzystać zaimplementowane w klasie metody. Obiekty możemy jednoznacznie identyfikować (takie rozróżnienie umożliwia wskaźnik this).

Z przedstawionych uproszczonych definicji klasy i obiektu wynika, że jedno nie może istnieć bez drugiego (nie można stworzyć obiektu, nie implementując wcześniej klasy). Przeanalizujmy tę relację na przykładzie datownika.

Przykład 1

Datownik jest specjalnym rodzajem pieczątki, umożliwiającym ustawienie dnia, miesiąca i roku, a następnie odciśnięcie ich na kartce papieru. Możemy go porównać do klasy. Datownik składa się z trzech danych (pól): dzień, miesiąc i rok; natomiast system pokręteł pozwala na modyfikacje wartości. Przybicie datownika powoduje odciśnięcie ustawionych na pokrętłach wartości. W ten sposób powstaje instancja klasy – obiekt. Zauważmy, że pieczątkę możemy przybić wielokrotnie. Każde odciśnięcie może przechowywać inne dane, które jednak zawsze będą opierać się na tym samym wzorcu, czyli klasie.

Klasy i obiekty w języku C++

W języku C++ klasy definiujemy w sposób podobny do strukturP13NkhXOWstruktur.

Linia 1. class NazwaKlasy otwórz nawias klamrowy. Linia 2. zamknij nawias klamrowy średnik.

Po słowie kluczowym class podajemy nazwę klasy. Dobrym zwyczajem jest rozpoczynanie nazwy klasy wielką literą. Poza tym nazewnictwo klas podlega takim samym zasadom, jakie stosowane są podczas nadawania nazw funkcjom i zmiennym.

W definicji klasy możemy umieścić następujące elementy:

  • atrybuty (pola) – elementy określające jakąś cechę lub daną przechowywaną wewnątrz obiektu; mogą nimi być dowolne zmienne, w tym obiekty klas albo tablice obiektów klas;

  • metody – określają zachowanie obiektów; są to funkcje składowe (funkcje związane z klasą) mające dostęp do atrybutów klasy;

  • informacje, z jakich klas dziedziczy definiowana klasa;

  • konstruktory oraz destruktory – pierwsze służą do tworzenia instancji klasy, drugie uruchamiane są przed usunięciem obiektu; konstruktor musi nazywać się tak samo jak klasa; nazwa destruktora składa się z nazwy konstruktora poprzedzonej znakiem tyldy (~);

  • specyfikatory dostępu – określające, kto ma dostęp do elementu klasy.

W uproszczeniu możemy porównać klasę do przepisu w książce kucharskiej, a obiekt do ugotowanej na jego podstawie potrawy.

Przeanalizujmy kod:

Linia 1. kratka include otwórz nawias ostrokątny iostream zamknij nawias ostrokątny. Linia 2. kratka include otwórz nawias ostrokątny cstdlib zamknij nawias ostrokątny. Linia 3. kratka include otwórz nawias ostrokątny string zamknij nawias ostrokątny. Linia 5. using namespace std średnik. Linia 7. class NazwaKlasy otwórz nawias klamrowy. Linia 8. otwórz nawias ostrokątny span class znak równości apostrof foreign apostrof lang znak równości apostrof en apostrof zamknij nawias ostrokątny private otwórz nawias ostrokątny prawy ukośnik span zamknij nawias ostrokątny dwukropek. Linia 9. int atrybut średnik. Linia 10. otwórz nawias ostrokątny span class znak równości apostrof foreign apostrof lang znak równości apostrof en apostrof zamknij nawias ostrokątny public otwórz nawias ostrokątny prawy ukośnik span zamknij nawias ostrokątny dwukropek. Linia 11. void metoda otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 12. cout otwórz nawias ostrokątny otwórz nawias ostrokątny cudzysłów Cialo metody cudzysłów otwórz nawias ostrokątny otwórz nawias ostrokątny endl średnik. Linia 13. zamknij nawias klamrowy. Linia 14. NazwaKlasy otwórz nawias okrągły int a zamknij nawias okrągły otwórz nawias klamrowy. Linia 15. atrybut znak równości a średnik. Linia 16. cout otwórz nawias ostrokątny otwórz nawias ostrokątny cudzysłów To jest konstruktor klasy cudzysłów otwórz nawias ostrokątny otwórz nawias ostrokątny endl średnik. Linia 17. zamknij nawias klamrowy. Linia 18. tylda NazwaKlasy otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 19. cout otwórz nawias ostrokątny otwórz nawias ostrokątny cudzysłów To jest destruktor klasy cudzysłów otwórz nawias ostrokątny otwórz nawias ostrokątny endl średnik. Linia 20. zamknij nawias klamrowy. Linia 21. zamknij nawias klamrowy średnik. Linia 23. int main otwórz nawias okrągły int argc przecinek char asterysk asterysk argv zamknij nawias okrągły otwórz nawias klamrowy. Linia 24. NazwaKlasy dowolnaNazwaObiektu otwórz nawias okrągły 5 zamknij nawias okrągły średnik. Linia 25. return 0 średnik. Linia 26. zamknij nawias klamrowy.

Zdefiniowaliśmy klasę NazwaKlasy, a następnie utworzyliśmy obiekt o nazwie dowolnaNazwaObiektu, korzystając z konstruktora opisanego w linii 14.

Po uruchomieniu programu na ekranie pojawią się dwie linie:

To jest konstruktor klasy
To jest destruktor klasy

Wynika to z faktu, że przed zakończeniem programu (instrukcja return 0 w linii 25.) wszystkie obiekty są usuwane.

Przykład 2

Napiszmy program symulujący działanie przywoływanego wcześniej datownika. Data jest opisywana trzema wartościami: dzień, miesiąc i rok – są to pola, które wypełniamy danymi. Datownik umożliwia manipulowanie pokrętłami i ustawienie interesującej nas daty. W programie za tę operację odpowiada metoda zmienDate. Odciśnięcie daty na kartce papieru symuluje metoda odcisnijDate. Jej zadaniem jest wydrukowanie na standardowym wyjściu wartości ustawionych w polach.

Linia 1. kratka include otwórz nawias ostrokątny iostream zamknij nawias ostrokątny. Linia 2. kratka include otwórz nawias ostrokątny cstdlib zamknij nawias ostrokątny. Linia 3. kratka include otwórz nawias ostrokątny string zamknij nawias ostrokątny. Linia 5. using namespace std średnik. Linia 7. class Datownik otwórz nawias klamrowy. Linia 8. protected dwukropek. Linia 9. int dzien średnik. Linia 10. int miesiac średnik. Linia 11. int rok średnik. Linia 12. public dwukropek. Linia 13. void zmienDate otwórz nawias okrągły int dzien przecinek int miesiac przecinek int rok zamknij nawias okrągły. Linia 14. otwórz nawias klamrowy. Linia 15. this minus zamknij nawias ostrokątny dzien znak równości dzien średnik. Linia 16. this minus zamknij nawias ostrokątny miesiac znak równości miesiac średnik. Linia 17. this minus zamknij nawias ostrokątny rok znak równości rok średnik. Linia 18. zamknij nawias klamrowy. Linia 19. Datownik otwórz nawias okrągły int dzien przecinek int miesiac przecinek int rok zamknij nawias okrągły. Linia 20. otwórz nawias klamrowy. Linia 21. this minus zamknij nawias ostrokątny dzien znak równości dzien średnik. Linia 22. this minus zamknij nawias ostrokątny miesiac znak równości miesiac średnik. Linia 23. this minus zamknij nawias ostrokątny rok znak równości rok średnik. Linia 24. zamknij nawias klamrowy. Linia 25. void odcisnijDate otwórz nawias okrągły zamknij nawias okrągły. Linia 26. otwórz nawias klamrowy. Linia 27. cout otwórz nawias ostrokątny otwórz nawias ostrokątny cudzysłów Data dwukropek cudzysłów otwórz nawias ostrokątny otwórz nawias ostrokątny dzien otwórz nawias ostrokątny otwórz nawias ostrokątny cudzysłów kropka cudzysłów otwórz nawias ostrokątny otwórz nawias ostrokątny miesiac otwórz nawias ostrokątny otwórz nawias ostrokątny cudzysłów kropka cudzysłów otwórz nawias ostrokątny otwórz nawias ostrokątny rok otwórz nawias ostrokątny otwórz nawias ostrokątny cudzysłów lewy ukośnik n cudzysłów średnik. Linia 28. zamknij nawias klamrowy. Linia 29. zamknij nawias klamrowy średnik. Linia 33. int main otwórz nawias okrągły int argc przecinek char asterysk asterysk argv zamknij nawias okrągły otwórz nawias klamrowy. Linia 34. Datownik datownik1 otwórz nawias okrągły 10 przecinek 10 przecinek 2010 zamknij nawias okrągły średnik. Linia 35. datownik1 kropka odcisnijDate otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 36. return 0 średnik. Linia 37. zamknij nawias klamrowy.
Ważne!

W języku C++ istnieją trzy specyfikatory dostępu:

  • public – informujący, że z każdego miejsca programu mamy dostęp do takiego elementu obiektu;

  • private – oznaczający, że tylko dany obiekt ma dostęp do danego elementu;

  • protected – specyfikator podobny do private.

Jeśli zastosowany jest konstruktor prywatny, to nie można zarówno utworzyć obiektu danej klasy, jak i dziedziczyć po niej.

Warto podkreślić, że możliwość tworzenia prywatnego konstruktora nie jest błędem twórców języka, a świadomą decyzją. Konstruktor prywatny przydaje się m.in. wtedy, gdy zależy nam istnieniu tylko jednej instancji danej klasy w całym programie (tzw. singleton).

Dziedziczenie

Dziedziczenie jest procesem, podczas którego kopiuje się funkcjonalności oraz zastosowania klasy bazowej do klasy pochodnej (dziedziczącej).

Ciekawostka

Jednym z pięciu podstawowych założeń programowania obiektowego (określanych akronimem SOLIDSOLIDSOLID) jest zasada sformułowana przez Barbarę Liskov. Mówi ona, że klasę dziedziczącą powinno dać się użyć w miejscu klasy bazowej. Innymi słowy, dobrą praktyką jest korzystanie z mechanizmu dziedziczenia w taki sposób, aby klasa pochodna nie zmieniała metod klasy bazowej.

Przykład 3
Linia 1. kratka include otwórz nawias ostrokątny iostream zamknij nawias ostrokątny. Linia 2. kratka include otwórz nawias ostrokątny cstdlib zamknij nawias ostrokątny. Linia 3. kratka include otwórz nawias ostrokątny string zamknij nawias ostrokątny. Linia 5. using namespace std średnik. Linia 7. class Pojazd otwórz nawias klamrowy. Linia 8. otwórz nawias ostrokątny span class znak równości apostrof foreign apostrof lang znak równości apostrof en apostrof zamknij nawias ostrokątny protected otwórz nawias ostrokątny prawy ukośnik span zamknij nawias ostrokątny dwukropek. Linia 9. int aktualnaPozycjaX średnik. Linia 10. int aktualnaPozycjaY średnik. Linia 11. otwórz nawias ostrokątny span class znak równości apostrof foreign apostrof lang znak równości apostrof en apostrof zamknij nawias ostrokątny public otwórz nawias ostrokątny prawy ukośnik span zamknij nawias ostrokątny dwukropek. Linia 12. void przemieszczenie otwórz nawias okrągły int oIleWx przecinek int oIleWy zamknij nawias okrągły otwórz nawias klamrowy. Linia 13. aktualnaPozycjaX plus znak równości oIleWx średnik. Linia 14. aktualnaPozycjaY plus znak równości oIleWy średnik. Linia 15. zamknij nawias klamrowy. Linia 16. Pojazd otwórz nawias okrągły int aktualnaPozycjaX przecinek int aktualnaPozycjaY zamknij nawias okrągły otwórz nawias klamrowy. Linia 17. otwórz nawias ostrokątny span class znak równości apostrof foreign apostrof lang znak równości apostrof en apostrof zamknij nawias ostrokątny this otwórz nawias ostrokątny prawy ukośnik span zamknij nawias ostrokątny minus zamknij nawias ostrokątny aktualnaPozycjaX znak równości aktualnaPozycjaX średnik. Linia 18. otwórz nawias ostrokątny span class znak równości apostrof foreign apostrof lang znak równości apostrof en apostrof zamknij nawias ostrokątny this otwórz nawias ostrokątny prawy ukośnik span zamknij nawias ostrokątny minus zamknij nawias ostrokątny aktualnaPozycjaY znak równości aktualnaPozycjaY średnik. Linia 19. zamknij nawias klamrowy. Linia 20. zamknij nawias klamrowy średnik. Linia 22. class Motocykl dwukropek otwórz nawias ostrokątny span class znak równości apostrof foreign apostrof lang znak równości apostrof en apostrof zamknij nawias ostrokątny otwórz nawias ostrokątny span class znak równości apostrof foreign apostrof lang znak równości apostrof en apostrof zamknij nawias ostrokątny public otwórz nawias ostrokątny prawy ukośnik span zamknij nawias ostrokątny otwórz nawias ostrokątny prawy ukośnik span zamknij nawias ostrokątny Pojazd otwórz nawias klamrowy. Linia 23. otwórz nawias ostrokątny span class znak równości apostrof foreign apostrof lang znak równości apostrof en apostrof zamknij nawias ostrokątny public otwórz nawias ostrokątny prawy ukośnik span zamknij nawias ostrokątny dwukropek. Linia 24. Motocykl otwórz nawias okrągły int aktualnaPozycjaX przecinek int aktualnaPozycjaY zamknij nawias okrągły dwukropek Pojazd otwórz nawias okrągły aktualnaPozycjaX przecinek aktualnaPozycjaY zamknij nawias okrągły otwórz nawias klamrowy. Linia 25. cout otwórz nawias ostrokątny otwórz nawias ostrokątny cudzysłów Jestem motocyklem cudzysłów otwórz nawias ostrokątny otwórz nawias ostrokątny endl średnik. Linia 26. zamknij nawias klamrowy średnik. Linia 27. int pobierzAktualnaPozycjeX otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 28. return aktualnaPozycjaX średnik. Linia 29. zamknij nawias klamrowy. Linia 30. int pobierzAktualnaPozycjeY otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 31. return aktualnaPozycjaY średnik. Linia 32. zamknij nawias klamrowy. Linia 33. zamknij nawias klamrowy średnik. Linia 36. int main otwórz nawias okrągły int argc przecinek char asterysk asterysk argv zamknij nawias okrągły otwórz nawias klamrowy. Linia 37. Motocykl honda otwórz nawias okrągły 0 przecinek 0 zamknij nawias okrągły średnik. Linia 38. honda kropka przemieszczenie otwórz nawias okrągły 5 przecinek 10 zamknij nawias okrągły średnik. Linia 39. cout otwórz nawias ostrokątny otwórz nawias ostrokątny cudzysłów Aktualna pozycja x dwukropek cudzysłów otwórz nawias ostrokątny otwórz nawias ostrokątny honda kropka pobierzAktualnaPozycjeX otwórz nawias okrągły zamknij nawias okrągły otwórz nawias ostrokątny otwórz nawias ostrokątny endl średnik. Linia 40. cout otwórz nawias ostrokątny otwórz nawias ostrokątny cudzysłów Aktualna pozycja y dwukropek cudzysłów otwórz nawias ostrokątny otwórz nawias ostrokątny honda kropka pobierzAktualnaPozycjeY otwórz nawias okrągły zamknij nawias okrągły otwórz nawias ostrokątny otwórz nawias ostrokątny endl średnik. Linia 41. return 0 średnik. Linia 42. zamknij nawias klamrowy.

Zasady dziedziczenia

Jeśli klasa, po której dziedziczymy, nie ma konstruktora bezparametrowego, należy jawnie wywołać konstruktor klasy bazowej (tak jak jest to widoczne w linii 24.  programu z przykładu 3). Podczas tworzenia obiektu klasy pochodnej zawsze uruchamiany jest konstruktor klasy bazowej, nawet jeśli dzieje się to niejawnie.

Dostępność elementów klasy bazowej w klasie pochodnej zależy od użytych specyfikatorów:

  • jeśli danym lub metodom towarzyszy specyfikator private, to elementy te nie są dostępne w klasie pochodnej;

  • jeśli danym lub metodom towarzyszy specyfikator public lub protected, są one dostępne w klasie pochodnej.

W linii 23. programu po dwukropku użyliśmy specyfikatora public. Warto pamiętać, że jeśli nie zastosujemy żadnego operatora, domyślnie zostanie użyty modyfikator private.  Specyfikator w tym miejscu służy do ograniczania widoczności w klasie. Jeśli zastosujemy w danej klasie specyfikator public, wszystkie jej elementy  również przyjmują typ public (mają najwyższą możliwą widoczność, czyli w praktyce nie zachodzi żadna zmiana w dostępności).

Modyfikator protected umożliwia dostęp do pola bądź metody w obrębie klasy bazowej oraz klas pochodnych (dziedziczących). Próba odwołania się do elementu, który został oznaczony protected, spoza wspomnianych wcześniej klas zakończy się błędem kompilacji.

Najbardziej restrykcyjnym modyfikatorem dostępu jest private. Uniemożliwia odwołanie się do elementu poprzez klasę dziedziczącą. Sprawa to, że tylko klasa, w której zostało utworzone pole bądź metoda, może korzystać z tak oznaczonego elementu.

Więcej na temat modyfikatorów dostępu dowiesz się z e‑materiału poświęconego paradygmatom programowania obiektowego w języku C++PzekSPtCrparadygmatom programowania obiektowego w języku C++.

Ważne!

W języku C++ istnieje wielodziedziczenie. Oznacza to, że klasa może dziedziczyć po wielu klasach jednocześnie.

Może to powodować problem w sytuacji, gdy dziedziczenie odbywa się po dwóch klasach, w których istnieje metoda o takiej samej nazwie. Przykładowo:

Linia 1. kratka include otwórz nawias ostrokątny iostream zamknij nawias ostrokątny. Linia 2. using namespace std średnik. Linia 3. class Klasa1. Linia 4. otwórz nawias klamrowy. Linia 5. public dwukropek. Linia 6. void test otwórz nawias okrągły zamknij nawias okrągły. Linia 7. otwórz nawias klamrowy. Linia 8. cout otwórz nawias ostrokątny otwórz nawias ostrokątny cudzysłów test1 cudzysłów średnik. Linia 9. zamknij nawias klamrowy. Linia 10. zamknij nawias klamrowy średnik. Linia 11. class Klasa2. Linia 12. otwórz nawias klamrowy. Linia 13. public dwukropek. Linia 14. void test otwórz nawias okrągły zamknij nawias okrągły. Linia 15. otwórz nawias klamrowy. Linia 16. cout otwórz nawias ostrokątny otwórz nawias ostrokątny cudzysłów test2 cudzysłów średnik. Linia 17. zamknij nawias klamrowy. Linia 18. zamknij nawias klamrowy średnik. Linia 19. class Test dwukropek public Klasa1 przecinek public Klasa2. Linia 20. otwórz nawias klamrowy. Linia 21. public dwukropek. Linia 22. Test otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 23. test otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 24. zamknij nawias klamrowy. Linia 25. zamknij nawias klamrowy średnik. Linia 27. int main otwórz nawias okrągły zamknij nawias okrągły. Linia 28. otwórz nawias klamrowy. Linia 29. Test test średnik. Linia 30. return 0 średnik. Linia 31. zamknij nawias klamrowy.

Problem w tym przypadku polega na tym, że kompilator nie jest w stanie stwierdzić, do której metody test() powinien się odwołać. Pojawia się błąd wskazujący na niejednoznaczność wywołanej metody:

Linia 1. main kropka cpp dwukropek 34 dwukropek 9 dwukropek error dwukropek reference to ‘test’ is ambiguous. Linia 2. 34 kreska pionowa test otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 3. kreska pionowa kareta tylda tylda tylda. Linia 4. main kropka cpp dwukropek 24 dwukropek 10 dwukropek note dwukropek candidates are dwukropek ‘void Klasa2 dwukropek dwukropek test otwórz nawias okrągły zamknij nawias okrągły ’. Linia 5. 24 kreska pionowa void test otwórz nawias okrągły zamknij nawias okrągły. Linia 6. kreska pionowa kareta tylda tylda tylda. Linia 7. main kropka cpp dwukropek 15 dwukropek 10 dwukropek note dwukropek ‘void Klasa1 dwukropek dwukropek test otwórz nawias okrągły zamknij nawias okrągły ’. Linia 8. 15 kreska pionowa void test otwórz nawias okrągły zamknij nawias okrągły. Linia 9. kreska pionowa kareta tylda tylda tylda.

Wskaźnik this

Wskaźnik this sygnalizuje początek obszaru pamięci zajmowanego przez obiekt (adres jego pierwszej komórki) i może służyć do jego jednoznacznej identyfikacji. Dwie różne instancje tej samej klasy będą miały dwa różne wskaźniki this, ponieważ są od siebie niezależne.

Widoczne jest tu podobieństwo do dwóch różnych zmiennych typu int. Mimo że obie zmienne mogą mieć taką samą wartość, to modyfikacja jednej z nich nie wpływa na wartość drugiej, ponieważ obie są zapisane pod innymi adresami w pamięci.

Linia 1. class Pojazd otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 2. otwórz nawias ostrokątny span class znak równości apostrof foreign apostrof lang znak równości apostrof en apostrof zamknij nawias ostrokątny protected otwórz nawias ostrokątny prawy ukośnik span zamknij nawias ostrokątny dwukropek. Linia 3. int aktualnaPozycjaX średnik. Linia 4. int aktualnaPozycjaY średnik. Linia 5. otwórz nawias ostrokątny span class znak równości apostrof foreign apostrof lang znak równości apostrof en apostrof zamknij nawias ostrokątny public otwórz nawias ostrokątny prawy ukośnik span zamknij nawias ostrokątny dwukropek. Linia 6. Pojazd otwórz nawias okrągły int aktualnaPozycjaX przecinek int aktualnaPozycjaY zamknij nawias okrągły otwórz nawias klamrowy. Linia 7. otwórz nawias ostrokątny span class znak równości apostrof foreign apostrof lang znak równości apostrof en apostrof zamknij nawias ostrokątny this otwórz nawias ostrokątny prawy ukośnik span zamknij nawias ostrokątny minus zamknij nawias ostrokątny aktualnaPozycjaX znak równości aktualnaPozycjaX średnik. Linia 8. otwórz nawias ostrokątny span class znak równości apostrof foreign apostrof lang znak równości apostrof en apostrof zamknij nawias ostrokątny this otwórz nawias ostrokątny prawy ukośnik span zamknij nawias ostrokątny minus zamknij nawias ostrokątny aktualnaPozycjaY znak równości aktualnaPozycjaY średnik. Linia 9. zamknij nawias klamrowy. Linia 10. zamknij nawias klamrowy.

Użycie wskaźnika this (jawne lub niejawne) jest konieczne, jeśli chcemy zapisać dane w polach. Za każdym razem, gdy modyfikujemy atrybut w danym obiekcie, robimy to za pośrednictwem wskaźnika this. W poprzednim fragmencie kodu w linii 6. zdefiniowaliśmy argumenty nazwane tak samo jak atrybuty klasy, jednak dzięki użyciu wskaźnika this w 7. i 8. linii kompilator rozpoznał, do której komórki pamięci należy przypisać wartości.

Operowanie na obiektach

Obiekty klas – podobnie jak zmienne każdego typu podstawowego – możemy umieścić w tablicy oraz podawać jako argumenty funkcji.

Funkcje w języku C++ domyślnie operują na kopiach zmiennych, które są przekazywane jako parametry. Tak samo jest w przypadku obiektów.

Powinniśmy jednak pamiętać, że obiekty, które są przekazywane jako argumenty do metod i funkcji, są kopiowane jedynie płytkokopiowanie płytkiepłytko.

Linia 1. kratka include otwórz nawias ostrokątny iostream zamknij nawias ostrokątny. Linia 2. kratka include otwórz nawias ostrokątny cstdlib zamknij nawias ostrokątny. Linia 3. kratka include otwórz nawias ostrokątny string zamknij nawias ostrokątny. Linia 5. using namespace std średnik. Linia 7. class NazwaKlasy otwórz nawias klamrowy. Linia 8. otwórz nawias ostrokątny span class znak równości apostrof foreign apostrof lang znak równości apostrof en apostrof zamknij nawias ostrokątny public otwórz nawias ostrokątny prawy ukośnik span zamknij nawias ostrokątny dwukropek. Linia 9. int a średnik. Linia 10. int asterysk tab średnik. Linia 11. NazwaKlasy otwórz nawias okrągły int a przecinek int asterysk tab zamknij nawias okrągły otwórz nawias klamrowy. Linia 12. otwórz nawias ostrokątny span class znak równości apostrof foreign apostrof lang znak równości apostrof en apostrof zamknij nawias ostrokątny this otwórz nawias ostrokątny prawy ukośnik span zamknij nawias ostrokątny minus zamknij nawias ostrokątny a znak równości a średnik. Linia 13. otwórz nawias ostrokątny span class znak równości apostrof foreign apostrof lang znak równości apostrof en apostrof zamknij nawias ostrokątny this otwórz nawias ostrokątny prawy ukośnik span zamknij nawias ostrokątny minus zamknij nawias ostrokątny tab znak równości tab średnik. Linia 14. zamknij nawias klamrowy. Linia 15. zamknij nawias klamrowy średnik. Linia 17. class DrugaKlasa otwórz nawias klamrowy. Linia 18. otwórz nawias ostrokątny span class znak równości apostrof foreign apostrof lang znak równości apostrof en apostrof zamknij nawias ostrokątny public otwórz nawias ostrokątny prawy ukośnik span zamknij nawias ostrokątny dwukropek. Linia 19. static void przykladowaMetoda otwórz nawias okrągły NazwaKlasy p zamknij nawias okrągły otwórz nawias klamrowy. Linia 20. p kropka tab otwórz nawias kwadratowy 0 zamknij nawias kwadratowy znak równości 5 średnik. Linia 21. zamknij nawias klamrowy. Linia 22. zamknij nawias klamrowy średnik. Linia 24. int main otwórz nawias okrągły int argc przecinek char asterysk asterysk argv zamknij nawias okrągły otwórz nawias klamrowy. Linia 25. int tab otwórz nawias kwadratowy 5 zamknij nawias kwadratowy znak równości otwórz nawias klamrowy 0 przecinek 1 przecinek 2 przecinek 3 przecinek 4 zamknij nawias klamrowy średnik. Linia 26. NazwaKlasy przykladowaKlasa otwórz nawias okrągły 5 przecinek tab zamknij nawias okrągły średnik. Linia 27. DrugaKlasa dwukropek dwukropek przykladowaMetoda otwórz nawias okrągły przykladowaKlasa zamknij nawias okrągły średnik. Linia 28. cout otwórz nawias ostrokątny otwórz nawias ostrokątny tab otwórz nawias kwadratowy 0 zamknij nawias kwadratowy średnik. Linia 29. return 0 średnik. Linia 30. zamknij nawias klamrowy.

Wynikiem działania przedstawionego programu będzie wypisanie na ekrannie liczby „5”, ponieważ kopiowanie było płytkie i metoda statyczna przykladowaMetoda() operowała na oryginalnej tablicy.

Przy okazji zastosowaliśmy również metodę statyczną, może być ona użyta bez powoływania obiektów. Metody statyczne wywołuje się zgodnie z następującą formułą:

NazwaKlasy::nazwaMetody()

Słownik

funkcja
funkcja

inaczej procedura, bądź podprogram, to wydzielona część programu wykonująca jakąś operacje; funkcja może być wykorzystywana wielokrotnie, upraszczając kod źródłowy programu

język imperatywny
język imperatywny

paradygmat programowania polegający na podziale programu na szereg instrukcji, które zmieniają stan programu (np. zmiennych); prawie każdy sprzęt komputerowy pracuje w sposób imperatywny

język strukturalny
język strukturalny

paradygmat programowania polegający na podziale kodu źródłowego programu na mniejsze części (procedury i bloki) z wykorzystaniem instrukcji kontrolnych (warunkowych) oraz pętli

kopiowanie płytkie
kopiowanie płytkie

(ang. shallow) polega na utworzeniu kopii obiektu ze skopiowanymi wartościami wszystkich atrybutów; kopiowane są również adresy wskaźników, jeśli któryś z atrybutów tego obiektu był tablicą lub wskaźnikiem

operator
operator

konstrukcja językowa jedno-, bądź wieloargumentowa zwracająca wartość

struktura danych
struktura danych

sposób przechowywania danych w pamięci komputera; na strukturach danych operują algorytmy

SOLID
SOLID

mnemonik zaproponowany przez Roberta C. Martina, opisujący pięć podstawowych założeń programowania obiektowego: zasady jednej odpowiedzialności (ang. single responsibility), zasady otwarte‑zamknięte (ang. open‑close), zasady podstawienia Liskov (ang. Liskov substitution principle), zasady segregacji interfejsów (ang. interface segregation principle) oraz zasady odwrócenia zależności (ang. dependency inversion principle)

wskaźnik
wskaźnik

logiczny adres wskazujący na miejsce w pamięci, w którym została umieszczona wartość zmiennej (zarówno statycznej, jak i dynamicznej)