Kris Jamsa Wygraj Z C++ lekcja23


Lekcja 23LEKCJA 23
Konstruktory i destruktory klas
Typową operacją przy tworzeniu obiektów w programach jest nadawanie wartości
początkowych składowym obiektu. Jak wiesz z lekcji 22, jedyną metodą dostępu do
prywatnych składowych klasy jest wywoływanie funkcji tej klasy. Aby uprościć
proces inicjalizowania składowych danych klasy, C++ zawiera pojęcie funkcji
konstruktor, która jest wywoływana dla każdego tworzonego w programie obiektu.
Analogicznie istnieje funkcja destruktor, wykorzystywana do usuwania obiektów.
Podczas tej lekcji przedstawimy szczegółowo konstruktory i destruktory. Pod
koniec tej lekcji będziesz rozumiał następujące zagadnienia podstawowe:
Konstruktor to metoda klasy, która ułatwia nadawanie wartości początkowych
składowym danych klasy.
Funkcja konstruktor ma taką samą nazwę jak klasa.
Konstruktory nie zwracają żadnej wartości.
Za każdym razem, gdy tworzysz w programie zmienną klasy, C++ wywołuje
konstruktor, jeśli go zdefiniowano.
Wiele obiektów zajmuje pamięć do przechowywania informacji. Podczas usuwania
obiektu C++ wywołuje funkcję destruktor, która zwalnia pamięć zajmowaną przez
obiekt, w pewnym sensie sprzątając po obiekcie.
Nazwa funkcji destruktor składa się z falki (~) i nazwy klasy.
Destruktory nie zwracają żadnej wartości.
Niech nie przestraszą Cię terminy konstruktor i destruktor. Powinieneś traktować
konstruktor jako funkcję, która pomoże Ci utworzyć (skonstruować) obiekt.
Analogicznie destruktor pomoże Ci usunąć obiekt. Najbardziej typowym
zastosowaniem destruktorów jest zwalnianie pamięci zajmowanej przez obiekt.


Jak utworzyć prosty konstruktor?
Funkcja konstruktor to metoda klasy nosząca tę samą nazwę co sama klasa. Na
przykład, jeśli korzystasz z klasy pod nazwą pracownik, to konstruktor również
będzie mieć nazwę pracownik. Analogicznie konstruktor klasy psy będzie nosić
nazwę psy. Jeśli zdefiniowałeś w programie konstruktor dla klasy, to C++ będzie
wywoływać automatycznie tę funkcję za każdym razem, gdy będziesz tworzyć obiekt
danej klasy. Przedstawiony poniżej program KONSTRUK.CPP definiuje klasę pod
nazwą pracownik. Definiuje dla niej konstruktor pracownik, który nadaje wartości
początkowe danym obiektu. Konstruktor jest funkcją nie zwracającą żadnej
wartości. Jednak nie deklarujesz go jako funkcji typu void, po prostu nie
podajesz typu funkcji:
class pracownik {
public:
pracownik (char *, long, float); //Funkcja konstruktor (nie określa
//typu zwracanej wartości)
void inf_o_prac (void);
int zmien_pensje (float);
long podaj_id (void);
private;
char imie_nazwisko[64];
long ident_pracownika;
float zarobki;
};

W programie definiujesz funkcję konstruktor tak jak dowolną inną metodę klasy:
pracownik::pracownik (char *imie_nazwisko, long ident_pracownika,
float zarobki)
{
strcpy (pracownik::imie_nazwisko, imie_nazwisko);
pracownik::ident_pracownika = ident_pracownika;
if (zarobki < 7000.00)
pracownik::zarobki = zarobki;
else
pracownik::zarobki = 0.0; //Podano niepoprawne zarobki
};

Jak widzimy, konstruktor nie zwraca żadnej wartości. Ale funkcja nie używa także
typu void. W definicji funkcji nazwy składowych są poprzedzone nazwą klasy i
operatorem widoczności, tak jak objaśnialiśmy podczas lekcji 22. Oto pełna
implementacja programu KONSTRUK.CPP:
#include
#include

class pracownik {
public:
pracownik (char *, long, float);
void inf_o_prac (void);
int zmien_pensje (float);
long podaj_id (void);
private;
char imie_nazwisko[64];
long ident_pracownika;
float zarobki;
}

pracownik::pracownik (char *imie_nazwisko, long ident_pracownika,
float zarobki)
{
strcpy (pracownik::imie_nazwisko, imie_nazwisko);
pracownik::ident_pracownika = ident_pracownika;
if (zarobki < 7000.00)
pracownik::zarobki = zarobki;
else
pracownik::zarobki = 0.0; //Podano niepoprawne zarobki
}

void pracownik::inf_o_prac (void)
{
cout << "Imię i nazwisko: " << imie_nazwisko << endl;
cout << "Ident: " << ident_pracownika << endl;
cout << "Zarobki: " << zarobki << endl;
};

void main(void)
{
pracownik informatyk ("Kris Jamsa", 101, 3000.0);

informatyk.inf_o_prac ();
}

Zwróć uwagę na to, że za deklaracją obiektu informatyk są jego wartości
początkowe w nawiasach, tak jak w wywołaniu funkcji. Gdy używasz konstruktorów,
to przekazujesz funkcji konstruktor parametry przy deklaracji obiektu:
pracownik informatyk ("Kris Jamsa", 101, 3000.0);

Gdybyś chciał korzystać w programie z różnych obiektów klasy pracownik, to
możesz nadać wartości początkowe (inicjalizować) składowym każdego obiektu przy
użyciu konstruktora, np.:
pracownik informatyk ("Kris Jamsa", 101, 3000.0);
pracownik sekretarka ("Janina Kowalska", 57, 300.0);
pracownik menedzer ("Jan Kowalski", 1022, 5000.0);

Znaczenie funkcji konstruktor
Konstruktor jest specjalną funkcją, którą C++ automatycznie wywołuje za każdym
razem, gdy tworzysz obiekt w programie. Typowym zastosowaniem konstruktora jest
nadawanie wartości początkowych składowym obiektu. Funkcje konstruktor mają tę
samą nazwę co klasa obiektu. Na przykład w klasie plik możesz zdefiniować
konstruktor pod nazwą plik. Definiujesz konstruktor w swoim programie tak samo
jak inne metody klasy. Różnica polega na tym, że dla funkcji konstruktor nie
podajesz typu zwracanej wartości. Gdy potem deklarujesz obiekt, to możesz
przekazywać konstruktorowi parametry tak jak tutaj:
nazwa_klasy obiekt (wartosc1, wartosc2, wartosc3);


Podawanie domyślnych wartości funkcjom konstruktor
Jak wiesz z lekcji 15, możesz w C++ podawać domyślne wartości parametrów
funkcji. Jeśli nie podasz w wywołaniu funkcji wartości żadnego parametru, to w
funkcjach będą wykorzystywane wartości domyślne. Konstruktory nie są pod tym
względem wyjątkiem. Możesz podawać w definicjach tych funkcji domyślne wartości
parametrów tak samo jak dla innych funkcji. Na przykład przedstawiony poniżej
konstruktor użyje domyślnej wartości zarobków 1000.0, jeśli program nie poda
zarobków przy tworzeniu obiektu. Jednak musi być podane nazwisko pracownika i
numer identyfikacyjny:
pracownik::pracownik (char *imie_nazwisko, long ident_pracownika,
float zarobki = 1000.00)
{
strcpy (pracownik::imie_nazwisko, imie_nazwisko);
pracownik::ident_pracownika = ident_pracownika;
if (zarobki < 7000.00)
pracownik::zarobki = zarobki;
else
pracownik::zarobki = 0.0; //Podano niepoprawne zarobki
}



Przeciążanie funkcji konstruktor
Jak wiesz z lekcji 13, możesz w programach w C++ przeciążać definicje funkcji
określając różne funkcje dla różnych typów parametrów. Możesz w taki sam sposób
przeciążać konstruktory. W przedstawionym poniżej programie PRZECKNS.CPP jest
przeciążona funkcja konstruktor pracownik. Pierwsza jej definicja wymaga podania
w programie nazwiska pracownika, jego numeru identyfikacyjnego i zarobków. Druga
wersja funkcji prosi użytkownika o wprowadzenie zarobków, jeśli program ich nie
podaje:
pracownik::pracownik (char *imie_nazwisko, long ident_pracownika)
{
strcpy (pracownik::imie_nazwisko, imie_nazwisko);
pracownik::ident_pracownika = ident_pracownika;
do {
cout << "Podaj zarobki pracownika " << imie_nazwisko
<< "mniejsze od 7 000: " ;
cin >> pracownik::zarobki;
} while (pracownik::zarobki >= 7000.0);
}

W definicji klasy musisz podać prototypy obu funkcji, czyli otrzymamy:
class pracownik {
public:

void inf_o_prac (void);
int zmien_pensje (float);
long podaj_id (void);
private;
char imie_nazwisko[64];
long ident_pracownika;
float zarobki;
};

Oto implementacja programu PRZECKNS.CPP:
#include
#include

class pracownik {
public:
pracownik (char *, long, float);
pracownik (char *, long);
void inf_o_prac (void);
int zmien_pensje (float);
long podaj_id (void);
private;
char imie_nazwisko[64];
long ident_pracownika;
float zarobki;
}

pracownik::pracownik (char *imie_nazwisko, long ident_pracownika,
float zarobki)
{
strcpy (pracownik::imie_nazwisko, imie_nazwisko);
pracownik::ident_pracownika = ident_pracownika;
if (zarobki < 7000.00)
pracownik::zarobki = zarobki;
else
pracownik::zarobki = 0.0; //Podano niepoprawne zarobki
}

pracownik::pracownik (char *imie_nazwisko, long ident_pracownika)
{
strcpy (pracownik::imie_nazwisko, imie_nazwisko);
pracownik::ident_pracownika = ident_pracownika;
do {
cout << "Podaj zarobki pracownika " << imie_nazwisko
<< "mniejsze od 7 000: " ;
cin >> pracownik::zarobki;
} while (pracownik::zarobki >= 7000.0);
}

void pracownik::inf_o_prac (void)
{
cout << "Imię i nazwisko: " << imie_nazwisko << endl;
cout << "Ident: " << ident_pracownika << endl;
cout << "Zarobki: " << zarobki << endl;
};

void main(void)
{
pracownik informatyk ("Kris Jamsa", 101, 3000.0);
pracownik menedzer ("Jan Kowalski", 102);

informatyk.inf_o_prac ();
menedzer..inf_o_prac ();
}

Gdy skompilujesz i uruchomisz ten program, to na ekranie zostanie wyświetlona
prośba o wpisanie zarobków Jana Kowalskiego. Po wprowadzeniu poprawnej sumy,
program wyświetli informacje o obu pracownikach.


Funkcje destruktor
Funkcja destruktor jest wywoływana automatycznie za każdym razem, gdy pro. gram
usuwa obiekt. Podczas dalszych lekcji dowiesz się, w jaki sposób można tworzyć
listy obiektów rozrastające się i zmniejszające w miare wykonywania programu.
Przy tworzeniu takich list program będzie dynamicznie przydzielać pamięć, w
której obiekty będą przechowywane (jeszcze nie umiesz tego robić). Wtedy obiekty
będą tworzone i usuwane podczas wykonywania programu i wtedy też zobaczysz, jaki
jest sens korzystania z destruktorów.
W każdym z utworzonych przez nas dotychczas programów obiekty były tworzone na
początku programu poprzez ich zadeklarowanie. Na końcu wykonywania programów C++
usuwa utworzone obiekty. Jeśli zdefiniujesz dla swoich klas destruktory, to C++
będzie automatycznie wywoływać te funkcje dla każdego obiektu na końcu programu
(gdy obiekty są usuwane). Nazwa destruktora dla klasy składa się z falki (~) i
nazwy klasy, np.

~nazwa_klasy (void)
{
// Instrukcje
}

W przeciwieństwie do konstruktorów, nie można przekazywać parametrów funkcjom
destruktor.
Przedstawiony poniżej program DESTRUKT.CPP definiuje następującą funkcję jako
destruktor dla klasy pracownik:
void pracownik::~pracownik (void)
{
cout << "Usuwam obiekt " << imie_nazwisko << endl;
}

W tym przykładzie funkcja destruktor po prostu wyświetla na ekranie informację,
że C++ usuwa obiekt. Na końcu programu C++ automatycznie wywołuje destruktor dla
każdego obiektu. Oto implementacja programu DESTRUKT.CPP:
#include
#include

class pracownik {
public:
pracownik (char *, long, float);
~pracownik (void);
void inf_o_prac (void);
int zmien_pensje (float);
long podaj_id (void);
private;
char imie_nazwisko[64];
long ident_pracownika;
float zarobki;
}

pracownik::pracownik (char *imie_nazwisko, long ident_pracownika,
float zarobki)
{
strcpy (pracownik::imie_nazwisko, imie_nazwisko);
pracownik::ident_pracownika = ident_pracownika;
if (zarobki < 7000.00)
pracownik::zarobki = zarobki;
else
pracownik::zarobki = 0.0; //Podano niepoprawne zarobki
}

void pracownik::~pracownik (void)
{
cout << "Usuwam obiekt " << imie_nazwisko << endl;
}

void pracownik::inf_o_prac (void)
{
cout << "Imię i nazwisko: " << imie_nazwisko << endl;
cout << "Ident: " << ident_pracownika << endl;
cout << "Zarobki: " << zarobki << endl;
};

void main(void)
{
pracownik informatyk ("Kris Jamsa", 101, 3000.0);

informatyk.inf_o_prac ();
}

Gdy skompilujesz i uruchomisz ten program, to otrzymasz na ekranie następujące
wyjście:
C:\> DESTRUKT
Imię i nazwisko: Kris Jamsa
Ident: 101
Zarobki: 3000
Usuwam obiekt Kris Jamsa

Jak widzimy, program automatycznie wywołuje destruktor bez potrzeby wstawiania
jawnego wywołania funkcji. Na razie zapewne nie będziesz korzystać w swoich
programach z destruktorów. Gdy jednak pisane przez Ciebie programy będą w
obiektach przydzielać pamięć, to możesz uznać, że funkcje destruktor dają
wygodną metodę zwalniania pamięci podczas usuwania obiektów.
Funkcje destruktor
Destruktor jest funkcją, którą C++ automatycznie wykonuje podczas usuwania
obiektu. Funkcje destruktor mają nazwy składające się z falki (~) i nazwy klasy,
np. ~prac. Możesz definiować destruktory w swoich programach w taki sam sposób
jak inne metody klasy.


Zapamiętaj
Konstruktory i destruktory to specjalne funkcje dla klasy, które są
automatycznie wywoływane podczas tworzenia lub usuwania obiektów. Większość
programów wykorzystuje konstruktory do nadawania wartości początkowych składowym
danych klasy. W prostych programach, jakie teraz tworzysz, nie będą zapewne
potrzebne destruktory. Podczas lekcji 24 nauczysz się, w jaki sposób można
przeciążać operatory. Innymi słowy, możesz tak przedefiniować symbol plus (+),
by dołączał zawartość jednego tekstu do drugiego. Jak już wiesz, dla danego typu
(np. char, float czy int) są zdefiniowane: zbiór wartości, jakie może
przechowywać zmienna tego typu oraz zbiór operacji, jakie programy mogą
przeprowadzać na wartościach typu. Definiując klasę w szczególności definiujesz
typ. C++ daje Ci możliwość określenia, w jaki sposób operatory będą działać na
wartościach tego typu. Zanim jednak przejdziemy do lekcji 24 upewnij się, że
opanowałeś już następujące zagadnienia podstawowe:
Konstruktor to specjalna funkcja, którą program automatycznie wywołuje za
każdym razem, gdy tworzysz obiekt. Konstruktor ma taką samą nazwę jak klasa
obiektu.
Konstruktory nie zwracają żadnej wartości, ale nie należy definiować ich typu
jako void. Po prostu trzeba pominąć typ wartości funkcji.
Gdy tworzysz w programie obiekt, to możesz przekazywać parametry funkcji
konstruktor w deklaracji obiektu.
Możesz w C++ przeciążać konstruktory i podawać domyślne wartości parametrów.
Destruktor jest specjalną funkcją, którą program automatycznie wywołuje za
każdym razem, gdy usuwasz obiekt. Konstruktor ma taką samą nazwę jak klasa
obiektu poprzedzona falką (~).



WsteczSpis treściDalej



Wyszukiwarka

Podobne podstrony:
Kris Jamsa Wygraj Z C lekcja32
Kris Jamsa Wygraj Z C lekcja 5
Kris Jamsa Wygraj Z C lekcja38
Kris Jamsa Wygraj Z C lekcja35
Kris Jamsa Wygraj Z C lekcja20
Kris Jamsa Wygraj Z C lekcja27
Kris Jamsa Wygraj Z C lekcja34
Kris Jamsa Wygraj Z C lekcja18
Kris Jamsa Wygraj Z C lekcja17
Kris Jamsa Wygraj Z C lekcja25
Kris Jamsa Wygraj Z C lekcja14
Kris Jamsa Wygraj Z C lekcja36
Kris Jamsa Wygraj Z C lekcja 4
Kris Jamsa Wygraj Z C lekcja33
Kris Jamsa Wygraj Z C lekcja 7
Kris Jamsa Wygraj Z C lekcja30
Kris Jamsa Wygraj Z C lekcja12
Kris Jamsa Wygraj Z C lekcja28
Kris Jamsa Wygraj Z C lekcja 6

więcej podobnych podstron