Ta lekcja jest rozszerzeniem klas. W programie z poprzedniej lekcji używaliśmy funkcji "wypełnij_klase", wywoływaliśmy ją po utworzeniu klasy w pamięci, aby zainicjować jej wartości. Klasy są wyposażone w specjalną funkcję, która nazywa się konstruktorem, a jej celem jest inicjacja pól w tej klasie, wywoływana jest ona automatycznie po utworzeniu klasy.
#include <iostream>
using namespace std;
class nazwa_klasy
{
public:
void funkcja();
nazwa_klasy();
//konstruktor, nie ma typu i ma nazwę klasy
private:
int liczba;
char litera;
};
nazwa_klasy::nazwa_klasy()
//konstruktor
{
//celem konstruktora jest zainicjowanie wartości w klasie, aby nie były to przypadkowe wartości z pamięci
liczba=
0
;
//zostaną one automatycznie zainicjowane po utworzeniu klasy
litera='a';
}
void nazwa_klasy::funkcja()
{
//jakaś funkcja w klasie
}
int main(
int argc,
char* argv[])
{
system(
"PAUSE"
);
return EXIT_SUCCESS;
}
Konstruktor jest funkcją, ale ma trzy niezwykłe cechy. Po pierwsze nie ma typu, zauważmy, że deklaruje się samą nazwę, bez typu! Po drugie właśnie nazwa, konstruktor jako funkcja musi mieć taką samą nazwę jak klasa. I trzecią niezwykłą rzeczą w tej funkcji jest to, że wywołuje się ona automatycznie po utworzeniu klasy w pamięci. W jej ciele należy przypisać wartości, które mają być zainicjowane konstruktorem. Konstruktory powinny być deklarowane w public, w przeciwnym wypadku, nie będziemy mogli ich użyć, gdyż konstruktor wywoływany jest z zewnątrz danej klasy(poza klasą).
KONSTRUKTOR Z PARAMETREM
Czasem trzeba tworzyć takie same klasy, które chcemy zainicjować innymi wartościami, wtedy robimy konstruktor, który będzie funkcją z parametrem. Mało tego, można nawet robić kilka konstruktorów w jednej klasie, stosując technikę przeciążania funkcji.
Konstruktor z parametrami:
#include <iostream>
using namespace std;
class nazwa_klasy
{
public:
void funkcja();
nazwa_klasy(
char lit);
//konstruktor z parametrem typu char
private:
int liczba;
char litera;
};
nazwa_klasy::nazwa_klasy(
char lit)
//konstruktor
{
liczba=
0
;
//załóżmy, że chcemy, żeby zawsze zmienna liczba miała wartość 0
litera=lit;
//ale załóżmy, że przy tworzeniu klasy, chcemy podać wartość zmiennej litera,
//wtedy zmiennej litera przypisujemy parametr konstruktora
}
void nazwa_klasy::funkcja()
{
//jakaś funkcja w klasie
}
int main(
int argc,
char* argv[])
{
nazwa_klasy Klasa('a');
system(
"PAUSE"
);
return EXIT_SUCCESS;
}
Teraz tworząc klasę należy podać parametr dla konstruktora.
PRZECIĄŻANIE KONSTRUKTÓW
#include <iostream>
using namespace std;
class nazwa_klasy
{
public:
void funkcja();
nazwa_klasy(
char lit);
//konstruktor z parametrem typu char
nazwa_klasy(
int licz,
char lit);
//konstruktor z dwoma parametrami
private:
int liczba;
char litera;
};
nazwa_klasy::nazwa_klasy(
char lit)
//konstruktor z parametrem
{
liczba=
0
;
litera=lit;
}
nazwa_klasy::nazwa_klasy(
int licz,
char lit)
//konstruktor z 2 parametrami
{
liczba=licz;
litera=lit;
}
void nazwa_klasy::funkcja()
{
//jakaś funkcja w klasie
}
int main(
int argc,
char* argv[])
{
nazwa_klasy Klasa1('b');
//klasa tworzona konstruktorem z parametrem
nazwa_klasy Klasa2(
2
,'c');
//klasa tworzona konstruktorem z dwoma parametrami
system(
"PAUSE"
);
return EXIT_SUCCESS;
}
Teraz nasza definicja klasy wyposażona jest w dwa konstruktory, różnią się one od siebie parametrami i w zależności od podanych parametrów przy tworzeniu, kompilator dobierze odpowiedni konstruktor.
DESTRUKTORY
Destruktor to funkcja, która jest odwrotnością konstruktora. Służy ona do wykonywania czynności przed usunięciem klasy z pamięci. Zasada działania jest podobna do działania konstruktora, funkcja jest wykonywana przed usunięciem obiektu z pamięci. Właściwie to rzadko wykorzystujemy destruktory, bo co możemy wykonywać przed usunięciem obiektu? Konstruktor przydatny jest, gdy w klasie mamy jakieś dynamicznie utworzone zmienne, destruktor może służyć do zwolnienia ich.
#include <iostream>
using namespace std;
class nazwa_klasy
{
public:
void funkcja();
nazwa_klasy();
//konstruktor
~nazwa_klasy();
//destruktor
private:
int liczba;
char litera;
};
nazwa_klasy::nazwa_klasy()
//konstruktor
{
liczba=
0
;
litera='a';
}
nazwa_klasy::~nazwa_klasy()
//destruktor
{
//ciało destruktora
}
void nazwa_klasy::funkcja()
{
//jakaś funkcja w klasie
}
int main(
int argc,
char* argv[])
{
system(
"PAUSE"
);
return EXIT_SUCCESS;
}
Deklaracja destruktora różni się od deklaracji konstruktora, tylko tym, że destruktor w nazwie na początku ma znak tyldy "~" (~nazwa_klasy).