-
Následující příklad ukazuje použití zřetězeného seznamu vytvořeného objektově
orientovaným způsobem.
class okno {
int delka;
int sirka;
okno *dalsi_okno;
public:
okno(void);
void nastav(int
nova_delka, int nova_sirka);
int ziskej_plochu(void);
void nastav_ukazatel(okno
*ktere_okno);
okno *ziskej_dalsi(void);
};
okno::okno(void){
delka = 8;
sirka = 8;
dalsi_okno
= NULL;
}
void okno::nastav(int
nova_delka, int nova_sirka){
delka = nova_delka;
sirka = nova_sirka;
}
int okno::ziskej_plochu(void){
return (delka
* sirka);
}
void okno::nastav_ukazatel(okno
*ktere_okno){
dalsi_okno
= ktere_okno;
}
okno *okno::ziskej_dalsi(void){
return dalsi_okno;
}
int main(int argc,
char **argv)
{
okno *start
= NULL;
// Vždy ukazuje na počátek seznamu
okno *temp;
// Pracovní ukazatel
okno *ukazatel_na_okno;
// Použito pro vytváření okna
for (int index
= 0; index < 10; index++){
// Generování seznamu
ukazatel_na_okno = new okno;
ukazatel_na_okno->nastav(index + 1, index + 3);
if (start == NULL)
start = ukazatel_na_okno;
// První prvek v seznamu
else
temp->nastav_ukazatel(ukazatel_na_okno);
// další prvek
temp = ukazatel_na_okno;
}
temp = start;
// Výpis seznamu
do {
cout << "Plocha okna je " << temp->ziskej_plochu() <<
endl;
temp = temp->ziskej_dalsi();
} while (temp
!= NULL);
temp = start;
// Zrušení seznamu
do {
temp = temp->ziskej_dalsi();
delete start;
start = temp;
} while (temp
!= NULL);
return 0;
}
Tento program vytváří zřetězený seznam 10 objektů, vypíše plochy těchto
objektů a seznam zruší. Zjistěte jak tento program pracuje.
-
Změňte předchozí program tak, aby zřetězený seznam obsahoval 1000000 prvků.
Přidejte také test k zjištění, zda každá dynamická alokace byla provedena.
Zajistěte, aby výstup obsahoval správné hodnoty.
-
Další program používá třídu vnořenou do třídy. Jedná se o velmi jednoduchý
příklad. Program obsahuje třídu okno, která byla značně zjednodušena
a jako jedna složka je do ní vložena třída, kterou jsme nazvali podtrida.
Tento objekt je pro použití přístupný pouze v implementaci třídy okno,
protože je zde také definován a žádná jeho definice se nevyskytuje v hlavím
programu.
class podtrida {
int hodnota1;
int hodnota2;
public:
void nastav(int
h1, int h2){ hodnota1 = h1; hodnota2 = h2;}
int ziskej_h2(void)
{return hodnota2;}
};
class okno {
int delka;
int sirka;
podtrida vn_trida;
public:
void nastav(int
d, int s, int h1, int h2){
delka = d;
sirka = s;
vn_trida.nastav(h1, h2);
}
int ziskej_plochu(void)
{return(delka * sirka);}
};
int main(int argc,
char **argv)
{
okno male,
stredni, velke;
male.nastav(2,
4, 1, 35);
stredni. nastav(5,
6, 2, 72);
velke.nastav(8,
10, 4, 98);
cout <<
"Plocha malého okna je " << male.ziskej_plochu() << endl;
cout <<
"Plocha středního okna je " << stredni.ziskej_plochu() << endl;
cout <<
"Plocha velkého okna je " << velke.ziskej_plochu() << endl;
}
Prostudujte si tento program a přidejte do něj příkazy, které vypíší
i hodnoty uložené ve vnořené třídě (bude-li potřeba, vytvořte i nové metody).
-
Následující program ukazuje překrývání operátorů. To umožňuje definovat
objekty třídy a redefinovat normální operátory. Výsledkem je, že objekty
nové třídy mohou být používány přirozeně jako předdefinované typy.
class okno {
int delka;
int sirka;
public:
void nastav(int
nova_delka, int nova_sirka);
int ziskej_plochu(void)
{return(delka * sirka);}
friend okno
operator+(okno a, okno b); // Součet dvou oken vedle sebe
friend okno
operator+(int a, okno b); // Přičtení konstanty k šířce okna
friend okno
operator*(int a, okno b); // Vynásobení okna konstantou
};
void okno::nastav(int
nova_delka, int nova_sirka){
delka = nova_delka;
sirka = nova_sirka;
}
okno operator+(okno
a, okno b){
okno pomocne;
pomocne.delka
= a.delka;
pomocne.sirka
= a.sirka + b.sirka;
return pomocne;
}
okno operator+(int
a, okno b){
okno pomocne;
pomocne.delka
= b.delka;
pomocne.sirka
= a + b.sirka;
return pomocne;
}
okno operator*(int
a, okno b){
okno pomocne;
pomocne.delka
= a * b.delka;
pomocne.sirka
= a * b.sirka;
return pomocne;
}
int main(int argc,
char **argv)
{
okno male,
stredni, velke;
okno pomocne;
male.nastav(2,
4);
stredni.nastav(5,
6);
velke.nastav(8,
10);
cout <<
"Plocha malého okna je " << male.ziskej_plochu() << endl;
cout <<
"Plocha středního okna je " << stredni.ziskej_plochu() << endl;
cout <<
"Plocha velkého okna je " << velke.ziskej_plochu() << endl;
pomocne =
male + stredni;
cout <<
"Plocha nového okna je " << pomocne.ziskej_plochu() << endl;
pomocne =
10 + male;
cout <<
"Plocha nového okna je " << pomocne.ziskej_plochu() << endl;
pomocne =
4 * velke;
cout <<
"Plocha nového okna je " << pomocne.ziskej_plochu() << endl;
return 0;
}
V našem programu jsou překryty operátory + a *. Jejich implementační
metody jsou deklarovány jako spřátelené funkce (pomocí klíčového slova
friend).
Jestliže nepoužijeme ?přátelskou konstrukci, pak funkce musí být částí
jednoho objektu a tomuto objektu budeme zasílat zprávy. Použití ?přátelské
konstrukce umožňuje oddělit tyto metody od objektu a volat je pomocí infixového
zápisu. Pomocí této techniky, můžou? konstrukci,
objekt1 + objekt2 namísto
objekt1.operator+(objekt2).
Bez přátelské konstrukce bychom také nemohli překrýt operátory, které mají
jako první parametr (operand) typ
int, neboť nelze zaslat zprávu
celočíselné proměnné. Dva ze tří překrytých operátorů používají int
pro první parametr a je tedy nutno je deklarovat jako spřátelené funkce.
Červený řádek ukazuje první překrytí, kdy je překrýván operátor +.
Zapisujeme návratový typ následovaný klíčovým slovem operator s
operátorem, který překrýváme. V závorkách jsou uvedeny dva formální parametry
a jejich typy a na následujících řádcích pokračuje implementace funkce.
První parametr určuje levý operand překrývaného operátoru a druhý pravý
operand. Na modrém řádku našeho programu je tato metoda volána pomocí infixového
zápisu namísto obvyklého formátu zasílání zpráv. Jelikož proměnné male
a strední jsou objekty třídy okno, systém hledá operátor
+ pro dva objekty třídy okno a nalezne náš první překrytý operátor.
Další překryté operátory používají jako levý operand hodnotu typu int.
Jinak pracují obdobně. Vyzkoušejte tento program. Změňte třetí řádek od
konce na
pomocne = velke *
4;
a zjistěte reakci na tuto změnu.
-
Další program ukazuje překrývání funkcí ve třídě. V tomto programu je pro
ilustraci překrýván konstruktor a jedna metoda.
class mnoho_jmen
{
int delka;
int sirka;
public:
mnoho_jmen(void);
mnoho_jmen(int
del);
mnoho_jmen(int
del, int sir);
void zobraz(void);
void zobraz(int
jeden);
void zobraz(int
jeden, int dva);
void zobraz(float
cislo);
};
mnoho_jmen::mnoho_jmen(void)
{
delka = 8;
sirka = 8;
}
mnoho_jmen::mnoho_jmen(int
del) {
delka = del;
sirka = 8;
}
mnoho_jmen::mnoho_jmen(int
del, int sir) {
delka = del;
sirka = sir;
}
void mnoho_jmen::zobraz(void)
{
cout <<
"Z funkce bez parametrů, plocha = " << delka * sirka << endl;
}
void mnoho_jmen::zobraz(int
jeden) {
cout <<
"Z funkce s jedním parametrem, plocha = "<<delka * sirka<<endl;
}
void mnoho_jmen::zobraz(int
jeden, int dva) {
cout <<
"Z funkce se dvěmi parametry, plocha = "<<delka * sirka<<endl;
}
void mnoho_jmen::zobraz(float
cislo) {
cout <<"Z
funkce s reálným parametrem, plocha = "<<delka * sirka<<endl;
}
int main(int argc,
char **argv)
{
mnoho_jmen
male, stredni(10), velke(12, 15);
int cele =
144;
float pi =
3.1415;
male.zobraz();
male.zobraz(100);
male.zobraz(cele,
100);
male.zobraz(pi);
stredni.zobraz();
velke.zobraz(pi);
return 0;
}
Tento program ukazuje překrytí metod. Zopakujme si, že funkce je vybrána
na základě počtu a typů parametrů. V našem případě jsou tři konstruktory.
Použitý konstruktor je určen počtem parametrů. V programu vytvoříme tři
objekty, každý pomocí jiného konstruktoru. Třída obsahuje dále čtyři metody
zobraz.
Zjistěte jak tento program pracuje.
-
V hlavičkovém souboru COMPLEX.H je deklarace standardní třídy complex
umožňující provádět výpočty s komplexními čísly. Podívejte se do tohoto
souboru, jak je třída deklarována. V nápovědě zjistěte, jaké operace, konstruktory
a spřátelené funkce zde můžeme používat.
-
Vytvořte program, který vypočítá hodnotu výrazu (A + B) / A
pro z klávesnice zadané komplexní hodnoty.
-
Vytvořte program, který bude pracovat jako jednoduchá kalkulačka v oblasti
komplexních čísel (sčítání, odečítání, násobení, dělení, a případně některé
funkce).
-
Deklarace typu třídy může začínat mimo klíčového slova class i struct
nebo union. Typ třídy mimo jiné ovlivňuje přístupová práva ke složkám.
Složky tříd typu class jsou implicitně soukromé (můžeme to změnit
specifikátory přístupu public nebo protected). Složky tříd
typu struct jsou implicitně veřejné (můžeme to změnit specifikátory
přístupu private nebo protected). Složky tříd typu union
jsou implicitně veřejné a toto nastavení nelze změnit. Vyzkoušejte (pokuste
se změnit typ některé existující třídy typu class na struct).
-
Uvažujte následující část programu:
class trida {
int x;
int y;
static int
pocet;
public:
void nastavx(int
novex) {x = novex; };
void nastavy(int);
void nastav(int
x, int y);
void nacti(trida
bod);
trida &predej();
};
int trida::pocet
= 0;
inline void trida::nastavy(int
novey){y = novey;}
void trida::nastav(int
x, int y){
this->x =
x;
this->y =
y;
}
void trida::nacti(trida
b){
x = 5 * b.x;
y = 5 * b.y;
this->x =
2*x;
this->y =
2*y;
this->x =
10 * b.x;
this->y =
10 * b.y;
}
V této ukázce si povšimněte několika věcí. Na identifikátoru parametru
v deklaraci nezáleží (viz metoda nacti) a tento identifikátor nemusí
být uveden (metoda nastavy). Metoda predej není implementována
a jestliže ji nikde nepoužijeme pak překladač nesignalizuje chybu. Metody
nastavx
a nastavy ukazují použití vložené funkce. V metodě nastav
jsou použita stejná jména parametrů jako jména složek třídy. Je zde ukázáno
jak pomocí ukazatele this můžeme v tomto případě přistupovat ke
složkám třídy. Složka pocet ukazuje použití globální složky (všechny
instance této třídy budou mít tuto složku společnou). Takovouto složku
je možno např. použít k počítání existujících instancí této třídy (v každém
konstruktoru této třídy položku inkrementujeme a v destruktoru dekrementujeme).
Tuto položku je nutno také definovat (dříve než vytvoříme první instanci
této třídy) a inicializovat. Tato třída neobsahuje žádný konstruktor ani
destruktor a jsou tedy vytvořeny překladačem automaticky.
Zjistěte, kdy v metodě nacti je použito které x a y.
Přidejte do této třídy konstruktor, destruktor a metodu zjišťující hodnotu
složky pocet a vyzkoušejte, že složku pocet je možno použít
k počítání instancí této třídy.
Základní pravidla pro metody:
-
Veřejné dělejte pouze ty metody, které uživatel potřebuje pro používání
třídy (veřejné rozhraní).
-
Soukromé dělejte ty metody, o nichž uživatel nepotřebuje vědět.
-
Chráněné dělejte ty metody, které mohou být zapotřebí v odvozených
třídách, ale uživatel o nich nepotřebuje vědět (viz dále).
-
Statické metody používejte pouze ve speciálních případech (viz dále).
-
Metody, které mají být provedeny rychle deklarujte jako vložené
funkce.
-
Z libovolného kódu, který se v programu vyskytuje několikrát vytvořte funkci.