Wstęp do programowania obiektowego w C++
Konstruktor
No to teraz do pełni szczęścia możemy dodać wspomniany już wcześniej konstruktor klasy. Najpierw jednak trochę teorii…
Konstruktor danej klasy to nic innego jak zwykła metoda nazwana dokładnie tak samo jak klasa. Idea konstruktora polega na tym, że operacje, które zawiera wykonywane są w momencie stworzenia obiektu danej klasy. Innymi słowy jeżeli mamy na przykład klasę JakasKlasa
:
class JakasKlasa { JakasKlasa() { //operacje tutaj zawarte zostaną uruchomione w momencie stworzenia obiektu tej klasy cout << "Stworzyłeś obiekt klasy JakasKlasa"; } };
To w momencie stworzenia jej obiektu w funkcji main
:
JakasKlasa obiekt;
Zostanie wywołana operacja z konstruktora czyli zostanie wyświetlony napis „Stworzyłeś obiekt klasy JakasKlasa
„.
Przykładowy kod do uruchomienia:
#include <iostream> using namespace std; class JakasKlasa { public: JakasKlasa() { //operacje tutaj zawarte zostaną uruchomione w momencie stworzenia obiektu tej klasy cout << "Stworzyłeś obiekt klasy JakasKlasa"; } }; int main() { JakasKlasa obiekt; //zostanie wypisany napis "Stworzyłeś obiekt klasy JakasKlasa" return 0; }
Pewnie zwróciłeś teraz uwagę na to, że konstruktor nie przyjmuje żadnych argumentów. Otóż konstruktor, który nie przyjmuje żadnych argumentów (tak jak powyżej w przykładzie) jest tak zwanym konstruktorem domyślnym. Konstruktor można oczywiście przeciążyć robi się to bardzo podobnie jak przeładowywanie nazw funkcji. Należy podać oczywiście inną liczbę argumentów, bądź argumenty innego typu. Tak więc konstruktorem przyjmującym jakieś argumenty nazywamy konstruktorem przeciążonym. Przykład:
#include <iostream> using namespace std; class JakasKlasa { public: JakasKlasa() { //operacje tutaj zawarte zostaną uruchomione w momencie stworzenia obiektu tej klasy cout << "Konstruktor domyślny"; } //konstruktor przeciążony JakasKlasa(string tekst) { cout << tekst << endl; } }; int main() { JakasKlasa obiekt("Konstrukotr przeciążony"); //zostanie wypisany napis "Konstruktor przeciążony" JakasKlasa obiekt1; //zostanie wypisany napis "Konstruktor domyślny" return 0; }
Efekt naszego kodu:
Konstrukotr przeciążony Konstruktor domyślny
Jak widać na powyższych przykładach konstruktor wywoływany jest w momencie stworzenia obiektu. W praktyce jest on więc wykorzystywany do inicjalizacji pól itd. czyli w skrócie do „usuwania śmieci”.
Wróćmy teraz do naszego przykładu:
#include <iostream> using namespace std; class Dlugopis { public: bool czyWysuniety = false; void pisz(string tekst) { if(czyWysuniety) cout << tekst; } }; int main() { Dlugopis dlugopis1; dlugopis1.pisz("Napisałeś ten tekst..."); //to nie zostanie napisane dlugopis1.czyWysuniety = true; dlugopis1.pisz("Wkład wysunięty?"); //to już zostanie napisane, bo wkład jest wysunięty return 0; }
I dopiszmy zwykły konstruktor domyślny, który zainicjalizuje pole czyWysuniety
:
#include <iostream> using namespace std; class Dlugopis { public: Dlugopis() { czyWysuniety = false; } bool czyWysuniety; void pisz(string tekst) { if(czyWysuniety) cout << tekst; } }; int main() { Dlugopis dlugopis1; dlugopis1.pisz("Napisałeś ten tekst..."); //to nie zostanie napisane dlugopis1.czyWysuniety = true; dlugopis1.pisz("Wkład wysunięty?"); //to już zostanie napisane, bo wkład jest wysunięty return 0; }
Jak widać powyżej konstruktor wstawiłem nad polem do którego odwołuję się w kodzie. Na kompilatorze GCC co prawda nie otrzymałem błędu ponieważ cała klasa jest jednym obiektem, a tworząc go (czyli w momencie uruchomienia konstruktora) pole jest już stworzone. Nie mniej tego typu zapis jest trochę nie logiczny i polecam go zamienić na taki:
class Dlugopis { public: bool czyWysuniety; Dlugopis() { czyWysuniety = false; } void pisz(string tekst) { if(czyWysuniety) cout << tekst; } };
Pamiętajcie również o tym, że konstruktor musi znajdować się w sekcji publiczne
ponieważ obiekty tworzymy poza klasą.
Nasz pierwszy obiektowy program ma już ręce i nogi.
Ćwiczenie
W ramach ćwiczeń polecam napisać coś podobnego, tworząc na przykład klasę Budzik
, gdzie będziemy mieć metody takie jak podajGodzine()
, ustawAlarm()
, godzinaAlarmu()
. Mogą one zwracać statyczny tekst, za wyjątkiem godzinaAlarmu()
gdzie powinna być zwracana godzina ustawiona za pomocą metody ustawAlarm()
. Dla osób bardziej ambitnych polecam napisanie sobie własnego stosu w C++, którego kod i sposób działania w Javie opisałem na łamach artykułu „Abstrakcyjne struktury danych: Stos„. Stos to po prostu obiekt (klasa), który oferuje „specyficzny” dostęp do danych.