Triedy v C++ 1. Úvod do tried

Similar documents
VYLEPŠOVANIE KONCEPTU TRIEDY

Databázové systémy. SQL Window functions

kucharka exportu pro 9FFFIMU

Spájanie tabuliek. Jaroslav Porubän, Miroslav Biňas, Milan Nosáľ (c)

Databázy (1) Prednáška 11. Alexander Šimko

Registrácia účtu Hik-Connect

Constraint satisfaction problems (problémy s obmedzujúcimi podmienkami)

Desatinné čísla #1a. Decimal numbers #1b. How much larger is 21,8 than 1,8? Desatinné čísla #2a. Decimal numbers #2b. 14 divided by 0,5 equals...

1 Komplexný príklad využitia OOP

Copyright 2016 by Martin Krug. All rights reserved.

Testovanie bieleho šumu

REPORT DESIGNER 1 VYTVORENIE A ÚPRAVA FORMULÁRA. úprava formulárov v Money S4 / Money S Vytvorenie formulára

Aplikačný dizajn manuál

Základná(umelecká(škola(Jána(Albrechta Topoľčianska(15

Poradové a agregačné window funkcie. ROLLUP a CUBE

TYPY, KONŠTANTY, PROCEDÚRY A FUNKCIE PRE PRÁCU S POĽOM

Objektovo-orientované programovanie

Anycast. Ľubor Jurena CEO Michal Kolárik System Administrator

Manuál k programu FileZilla

Textový formát na zasielanie údajov podľa 27 ods. 2 písm. f) zákona

TP-LINK 150Mbps Wireless AP/Client Router Model TL-WR743ND Rýchly inštalačný sprievodca

Portál pre odborné publikovanie ISSN

Tvorba informačných systémov. 4. prednáška: Návrh IS

Recipient Configuration. Štefan Pataky MCP, MCTS, MCITP

Spôsoby zistenia ID KEP

package balik; public class TopLevel1 {... }

UNIVERZITA KOMENSKÉHO V BRATISLAVE FAKULTA MATEMATIKY, FYZIKY A INFORMATIKY VÝUKOVÁ WEBOVÁ APLIKÁCIA NA PROGRAMOVANIE GPU.

Obrázok č. 1 Byte. Obrázok č. 2 Slovo

Programovanie v jazyku Python. Michal Kvasnica

VLSM a CIDR. CCNA2 Kapitola Cisco Systems, Inc. All rights reserved. Cisco Public 1

Databázy (1) Prednáška 08. Alexander Šimko

Obsah. SOA REST REST princípy REST výhody prest. Otázky

Jeden z variantov príkazu priradenia nám umožňuje zadať za sebou aj viacej vstupných hodnôt, ako napríklad

1 Vytvorenie tabuľky

CUIT. Coded UI Testing

Vnorené SQL. Autor prezentácie: Peter Šípoš

Programovanie v jazyku C - modularita

Stretnutie s Pascalom II.

VYSOKÉ UČENÍ TECHNICKÉ V BRNĚ

Informatika 2. Generiká

PRACOVNÝ ZOŠIT Z PROGRAMOVANIA 2

Entity Framework: Úvod

Automatizovanie navrhovania objektov v prostredí Autocad

Osobovo-orientovaný prístup vývoja softvéru

18. Matlab figure ako objekt

Rýchlosť Mbit/s (download/upload) 15 Mbit / 1 Mbit. 50 Mbit / 8 Mbit. 80 Mbit / 10 Mbit. 10 Mbit / 1 Mbit. 12 Mbit / 2 Mbit.

POKROČILÉ C++ Marian Vittek

/* toto je viacriadková poznámka */ ako v Delphi, len sa rozlišujú malé a veľké písmená!!!

MS Exchange 2010 Prechod Ing. Peter Záhradník

Go networking. Peter Borovanský, KAI, I-18, borovan(a)ii.fmph.uniba.sk

ITS ČESTNÉ PREHLÁSENIE. 1 Čestné prehlásenie

2 Grafické knižnice a systémy

Databázy (2) Prednáška 08. Alexander Šimko

Microsoft Azure platforma pre Cloud Computing. Juraj Šitina, Microsoft Slovakia

2. prednáška ( )

Using Parallel Arrays. Parallel Array Example

Nástroj na detekciu indikátorov kompromitácie v systémoch Windows

Riešenia a technológie pre jednotnú správu používateľov

Systém pre podporu výuky teórie programovacích jazykov

Linked List using a Sentinel

systemove programovanie win32 programovanie

Univerzita Karlova v Praze Matematicko-fyzikální fakulta BAKALÁŘSKÁ PRÁCE. Andrej Kruták

JAVA. Sieťové programovanie

AKO NA RIZIKÁ. Hurá metóda asi nebude správna. Jaroslav Grega. Čo je riziko? Čo je manažment rizík

METODIKA TVORBY PRE ZÁKLADNÉ ŠKOLY ŠKOLSKÝCH VZDELÁVACÍCH PROGRAMOV

Univerzita Komenského v Bratislave Fakulta matematiky, fyziky a informatiky. Interaktívna výuková webová aplikácia na riešenie úloh o pravdepodobnosti

obsahuje 5 príkladov, spolu 29>25 bodov skupina:

Jazyk SQL. Jaroslav Porubän, Miroslav Biňas, Milan Nosáľ (c)

Kapitola 8 Začíname s programom Base

Malé velké databázy III. / 1. cast

CMPS 221 Sample Final

Ochrana proti DDoS za použitia open-source software. Katarína Ďurechová

Mesačná kontrolná správa

Komunikačné protokoly 2005 KP 2005 #3 - IP v02.doc

Tvorba plánov v softvérovom projekte, rozdelenie úloh, plnenie a aktualizácia plánov

LL LED svietidlá na osvetlenie športovísk. MMXIII-X LEADER LIGHT s.r.o. Všetky práva vyhradené. Uvedené dáta podliehajú zmenám.

SLOVENSKÁ TECHNICKÁ UNIVERZITA FAKULTA INFORMATIKY A INFORMAČNÝCH TECHNOLÓGIÍ ILKOVIČOVA 3, BRATISLAVA 4

Vzorové riešenia 2. kola zimnej časti

IMPLEMENTACE MODULÁRNÍ ARITMETIKY DO OBVODŮ FPGA A ASIC

6. Riadenie chodu programu

Fundamentals of Programming. Lecture 19 Hamed Rasifard

3D Modelovanie a vizualizácia matematických dát

UNIVERZITA KOMENSKÉHO V BRATISLAVE FAKULTA MATEMATIKY, FYZIKY A INFORMATIKY

MATLAB EXCEL BUILDER A NÁVRH PID REGULÁTOROV PRE PROSTREDIE MS EXCEL

7. UKAZOVATELE, POLIA A REŤAZCE

Computer Programming

Object oriented programming

Refaktorovanie jazyka JavaScript a DHTML

C++ Scope Resolution Operator ::

GRAFIKA V JAZYKU C (knižnica SDL)

e-scheme Návod na použitie

Name SECTION: 12:45 2:20. True or False (12 Points)

Mesačná kontrolná správa

CMSC 202 Midterm Exam 1 Fall 2015

Aplikačný rámec Spring. Róbert Novotný.

Fuzzy teoria a jazyk SQL

Komunikačné protokoly 2004 KP 2004 #3 - IP v03.doc

Analýza a vizualizácia veľkých dát

Február Scrum: Vyvinuli a udržiavajú Ken Schwaber a Jeff Sutherland

C++ basics Getting started with, and Data Types.

Transcription:

1. Úvod do tried Používanie nového dátového typu ktorý budeme oht class trieda nás dovedie k využívaniu objektových vlastností jazyka C++. Tento nový typ programov OOP objektovo orientované programovanie výrazne zjednodušuje nielen programovanie samotné, ale i jeho najdôležitejšiu časť návrh. My sme sa už s používaním tried stretli. Napríklad string je tiež trieda a aby sme ju mohli využívať, potrebujem natiahnuť do programu príslušnú knižnicu pomocou kľúčového slova include. Najväčšou zmenou pri tvorbe tohto nového dátového typu je to,že trieda obsahuje nielen funkcie ale i dáta. Samotná trieda je ale len abstraktný predpis, ktorý určuje, ako sa bude správať premenná daného typu. Túto premennú nazývame objekt. Tak ako premenná typu int vznikne až počas jej deklarácie : int ncislo; tak i objekt vznikne až pri jeho deklarácii. To znamená, že ak vytvoríme triedu a pomenujeme ju napr. CSkola (je zvykom dať pred meno písmeno C a hneď vieme, že sa jedná o triedu.) tak samotný objekt (reálna premenná ktorá zaberá miesto v pamäti) vznikne pri jeho deklarácii CSkola skola; Je zvykom rozdeliť si programovanie triedy na deklaráciu triedy (vytvoríme názov objektu, deklarujeme jeho funkcie a premenné.) a jej definíciu (Pri definícii funkcií vytvárame jej telo píšeme sadu príkazov v bloku. ) do dvoch súborov. Názvy súborov je možné zvoliť ľubovoľne a je preto výhodné zvoliť si taký istý názov súborov aké je meno triedy. Deklarácie umiestňujeme do súboru s príponou.h a jej definíciu so súboru s príponou.cpp. Konečne vidíme, načo v priečinku projektu podpriečinky header a source.: Začnime deklaráciou v súbore CSkola.h: class CSkola //Funkcie CSkola(void); //konstruktor ~CSkola(void); //destruktor ; //Data Každá trieda musí mať dve základné funkcie: konštruktor a deštruktor. Funkcia konštruktor sa vykoná pri vzniku objektu a funkcia deštruktor pri jeho zániku. Obe funkcie musia mať rovnaký názov ako meno triedy. Funkcia deštruktor má pred menom vlnovku ~(tilda). Naproti 1

tomu pri definícii triedy (v súbore CSkola.cpp musíme naprogramovať, čo má funkcia robiť: Slovíčko public si vysvetlíme neskôr. #include "CSkola.h" #include <iostream> #include <string> using namespace std; CSkola::CSkola(void) //konstruktor triedy univerzal cout << "konstruktor triedy zakladny " << endl; CSkola::~CSkola(void) //destruktor triedy univerzal cout << "destruktor triedy zakladny " << endl; V našom prípade iba vypíšeme, že objekt vzniká (v konštruktore) resp. zaniká (v deštruktore). Všimnime si, že pred menom funkcie ešte musíme pripísať, kde je táto funkcia viditeľná (scope operátor :: ) v našom prípade je funkcia CSkola() viditeľná v triede CSkola. CSkola::CSkola(void) Na začiatku súboru CSkola.cpp musíme k programu pripojiť deklaráciu našej triedy pomocou include musíme natiahnuť knižnicu, v ktorej sme triedu zadeklarovali. Pozor táto knižnica nie je medzi ostatnými knižnicami, ale je v priečinku ktorý sme si zvolili ako priečinok projectu. Takto vytvorenú triedu môžeme použiť v hlavnom programe na vytvorenie objektu: #include "CSkola.h" #include <iostream> #include <string> using namespace std; int main(void) CSkola skola; int cislo = 0; cout << " Zadaj cele cislo na skoncenie "<< endl; cin >> cislo; return 0; Samozrejme musíme i v hlavnom programe zavolať knižnicu: #include "CSkola.h". Stalo sa ale, že knižnice <iostream> a <string> ako i namespace som vlastne zavolal dvakrát. V main.cpp i CSkola.cpp. Toto nie je dobré z hľadiska plytvania času a pamäte. Kde teda máme tieto knižnice includovať? Stačí to len raz a to práve v CSkola.h. Výsledok je takýto: CSkola.h: #include <iostream> #include <string> using namespace std; class CSkola 2

//Funkcie CSkola(void); //konstruktor ~CSkola(void); //destruktor ; //Data CSkola.cpp: main.cpp: #include "CSkola.h" CSkola::CSkola(void) //konstruktor triedy univerzal cout << "konstruktor triedy zakladny " << endl; CSkola::~CSkola(void) //destruktor triedy univerzal cout << "destruktor triedy zakladny " << endl; #include "CSkola.h" int main(void) CSkola skola; int cislo = 0; cout << " Zadaj cele cislo na skoncenie "<< endl; cin >> cislo; return 0; A základ programu je hotový. Je to síce prvé použitie triedy, ale táto trieda (CSkola) dokáže iba vzniknúť a zaniknúť. Pridajme k nej nejaké dáta a funkcie. Najprv deklarácia v hlavičkovom súbore (headri): class CSkola //Funkcie CSkola(void); //konstruktor ~CSkola(void); //destruktor void ZadajMeno(void); void VypisMeno(void); ; //Data string smenoskoly; int npocettried; A definícia v zdrojovom súbore: void CSkola::ZadajMeno(void) cout << "Zadaj meno skoly " << endl; cin >> smenoskoly; void CSkola::VypisMeno(void) 3

cout << "Meno skoly je: " << smenoskoly << endl; Takto vzniknuté súbory môžeme zavolať v hlavnom programe: #include "CSkola.h" int main(void) CSkola skola; skola.zadajmeno(); skola.vypismeno(); int cislo = 0; cout << " Zadaj cele cislo na skoncenie "<< endl; cin >> cislo; return 0; Všimnite si, že k funkciám i dátam triedy pristupujeme pomocou bodky (zatiaľ): skola.zadajmeno(); Spomínate si na slovo.length();? Aj typ string je trieda a length() je funkcia, ktorá zistí dĺžku slova. A keďže je to funkcia zátvorky sú nevyhnuté aj keď nezadávame žiadme argumenty (resp. zadávame void). Takisto samozrejme pristupujeme i k dátam triedy (funkcie i dáta patriace danej triede nazývame členské dáta a funkcie danej triedy). #include "CSkola.h" int main(void) CSkola skola; skola.zadajmeno(); skola.vypismeno(); cout << "Zadaj nove meno: "<< endl; cin >> skola.smenoskoly; cout << "Nove meno je: " << skola.smenoskoly << endl; int cislo = 0; cout << "Zadaj cele cislo na skoncenie "<< endl; cin >> cislo; return 0; To by bol zhruba úvod do dátového typu trieda. Úlohy: 1. Doplňte triedu CSkola o funkcie na zadávanie počtu tried v škole, o výpis tohto počtu. 2. Doplňte triedu CSkola o funkciu na zadávanie počtu žiakov v jednej triede (toto bude nová členská premenná) a o výpis celkového počtu žiakov v škole. 4

2. Používanie viacerých konštruktorov Doteraz sme pri vzniku objektu danej triedy použili jednoduchý konštruktor. Je výhodné pri deklarovaní nového objektu danej triedy hneď aj nastaviť niektoré jeho členské premenné. Na to využijeme konštruktory s predávanými parametrami (argumenty, ktoré vchádzajú do funkcie). Napr. zoberme si zjednodušenú verziu predchádzajúceho projektu s triedou CSkola. Main.cpp: #include "CSkola.h" int main(void) CSkola skola; system("pause"); return 0; CSkola.h: #include <iostream> #include <string> using namespace std; class CSkola //Funkcie CSkola(void); //konstruktor ~CSkola(void); //destruktor ; //Data string smenoskoly; int npocettried; CSkola.cpp: #include "CSkola.h" CSkola::CSkola(void) //konstruktor triedy univerzal CSkola::~CSkola(void) //destruktor triedy univerzal Ak v hlavnom programe deklarujeme nový objekt typu CSkola : Main.cpp: CSkola skola; Členské premenné nemajú zadané žiadne hodnoty. Skúsme si ich vypísať: Je vhodné preto v konštruktore definovať nejaké ich default hodnoty: 5

Ale to tiež nie je vhodné riešenie. Chceli by sme, aby objekt skola vznikol s menom, koré napr. sme načítali tesne pre jeho deklaráciou: Main.cpp: int main(void) string sslovo = " "; cout << "Zadaj meno skoly : " << endl; cin >> sslovo; CSkola skola(sslovo); cout << "Meno skoly je: " << skola.smenoskoly <<" jej pocet tried je: " << skola.npocettried << endl; system("pause"); return 0; Na to ale musí existovať v nami vytvorenej knižnici CSkola ďalší konštruktor: CSkola.h: class CSkola //Funkcie CSkola(void); //konstruktor CSkola(string sword); //konstruktor so zadanim mena ~CSkola(void); //destruktor void ZadajMeno(void); void VypisMeno(void); ; //Data string smenoskoly; int npocettried; CSkola.cpp: #include "CSkola.h" CSkola::CSkola(void) //konstruktor triedy univerzal smenoskoly = "Neznama"; //default hodnota npocettried = 5; //default hodnota CSkola::CSkola(string sword) //konstruktor triedy univerzal smenoskoly = sword; // do clenskej premennej triedy ulozime hodnotu parametru funkcie npocettried = 5; //default hodnota CSkola::~CSkola(void) //destruktor triedy univerzal Samozrejme môžeme vytvoriť i ďalší konštruktor, do ktorého vložíme i npocettried: 6

CSkola::CSkola(string sword, int npocet) //konstruktor triedy univerzal smenoskoly = sword; // do clenskej premennej triedy smenoskoly ulozime hodnotu parametru funkcie npocettried = npocet; //do clenskej premennej triedy npocettried ulozime hodnotu parametru funkcie Teraz môže objekt skola s ľubovoľným konštruktorom vyberieme si. Prípadne vytvoríme viacero objektov pomocou rôznych konštruktorov: int main(void) CSkola skola1; string sslovo = " "; cout << "Zadaj meno skoly 2 : " << endl; cin >> sslovo; CSkola skola2(sslovo); cout << "Zadaj meno skoly 3 : " << endl; cin >> sslovo; int np = 0; cout << "Zadaj pocet tried skoly 3 : " << endl; cin >> np; CSkola skola3(sslovo, np); cout << "Meno skoly 1 je: " << skola1.smenoskoly <<" jej pocet tried je: " << skola1.npocettried << endl; cout << "Meno skoly 2 je: " << skola2.smenoskoly <<" jej pocet tried je: " << skola2.npocettried << endl; cout << "Meno skoly 3 je: " << skola3.smenoskoly <<" jej pocet tried je: " << skola3.npocettried << endl; system("pause"); return 0; Pozor!!! Deštruktor môže byť iba jeden. Takisto môžeme vytvoriť viacero členských funkcií s rovnakým menom, ale s rôznymi vstupnými parametrami (a teda rôzne pracujúce funkcie). Napríklad určite potrebujeme funkciu na zadávania meno školy a na zadávanie počtu tried. Môžeme to urobiť rôzne : vložíme meno ako parameter funkcie, alebo do funkcie nevložíme nič a celé načítanie i dosadenie do premennej sa udeje vo vnútri funkcie: CSkola.h: void ZadajMeno(void); void ZadajMeno(string smenoin); void ZadajPocetTried(void); void ZadajPocetTried(int npocetin); 7

CSkola.cpp: void CSkola::ZadajMeno(string smenoin) smenoskoly = smenoin; //do clenskej premennej triedy smenoskoly ulozime hodnotu parametru funkcie void CSkola::ZadajMeno(void) //smenoskoly zadame vo vnutri funkcie cout << "Zadaj meno skoly " << endl; cin >> smenoskoly; void CSkola::ZadajPocetTried(int npocetin) npocettried = npocetin; //do clenskej premennej triedy npocettried ulozime hodnotu parametru funkcie void CSkola::ZadajPocetTried(void) //npocettried zadame vo vnutri funkcie Main.cpp:... cout << "Zadaj pocet tried skoly " << endl; cin >> npocettried; skola1.zadajmeno("javorka"); skola2.zadajpocettried(12); //alebo skola1.zadajmeno(); skola2.zadajpocettried();... Pozrime sa teraz na kľúčové slovo V preklade to znamená, že jak členské premenné tak i členské funkcie deklarované za týmto slovom sú verejné, teda viditeľné napríklad aj vo funkcii main a môžeme ich čítať ako i do nich zapisovať hodnoty a pristupujeme k nim pomocou bodky za objektom: Main.cpp: skola3.smenoskoly = "Strojarka"; skola1.zadajmeno(); int ncislo = skola3.npocettried; Mať verejné public členské dáta nie je veľmi výhodné. Je oveľa výhodnejšie skryť ich všade okrem samotnej triedy. Napríklad smenoskoly deklarujeme ako súkromné private: CSkola.h: class CSkola //Funkcie CSkola(void); //konstruktor CSkola(string sword); //konstruktor so zadanim mena CSkola(string sword, int npocet); ~CSkola(void); //destruktor void ZadajMeno(void); void ZadajMeno(string smenoin); void ZadajPocetTried(void); void ZadajPocetTried(int npocetin); 8

//Data int npocettried; private: string smenoskoly; ; V tom momente pri každom pokuse o prístup k premennej smenoskoly zahlási prekladač chybu: error C2248: 'CSkola::sMenoSkoly' : cannot access private member declared in class 'CSkola' To znamená, že mimo triedy už k premennej smenoskoly nemáme prístup. Ako teda vypíšeme obsah tejto premennej? Musíme zaviesť pre výpis tejto premennej funkciu vo vnútri triedy CSkola. Všetky členské funkcie majú k premenným svojej triedy vždy prístup private člen triedy (a môže to byť i funkcia) je súkromný pre svoju triedu. Musíme teda vytvoriť funkciu: CSkola.h: string VratMenoSkoly(void); do ktorej nemusíme nič zadávať, ale ktorá nám vráti hodnotu členskej premennej smenoskoly': CSkola.cpp: string CSkola::VratMenoSkoly(void) return smenoskoly; Stačí potom túto zavolať: Main.cpp: cout << "Meno skoly 1 je: " << skola1.vratmenoskoly() <<" jej pocet tried je: " << skola1.npocettried << endl; Je dokonca zvykom písať kľúčové slova public a private zvlášť pre funkcie i dáta, i keď ich nevyužijeme. Ak by sme tieto kľúčové slová neuviedli, všetci členovia triedy by boli automaticky private. CSkola.h: class CSkola //Funkcie private: CSkola(void); // default konstruktor CSkola(string sword); //konstruktor so zadanim mena CSkola(string sword, int npocet); //konstruktor so zadanim mena a poctu tried ~CSkola(void); //destruktor void ZadajMeno(void); void ZadajMeno(string smenoin); void ZadajPocetTried(void); void ZadajPocetTried(int npocetin); string VratMenoSkoly(void); //Data private: string smenoskoly; int npocettried; ; 9

To by bolo na začiatok. Teraz zopár úloh pre vás: Úlohy: 1. Doplňte triedu CSkola o funkcie void VypisMenoSkoly(void); //Cely vypis je vo vnutri funkcie (cout...) int VratPocetTried(void); // Vrati pocet tried v skole void VypisPocetTried(void); //Cely vypis je vo vnutri funkcie (cout...) 2. Ak máme tieto funkcie, môžeme aj smenoskoly aj npocettried deklarovať ako private. 3. Skúste deklarovať v main objekty skola ako pole. Využite default konstruktor a potom v cykle zadajte mená škôl a v ďalšom cykle počty tried pre tieto školy. Výzva na zadanie počtu tried je aj s menom školy, napríklad: Zadajte počet tried v škole Orange 4. Vypíšte v cykle ktoré školy majú koľko tried. 3. Ďalšia vnorená trieda (a pritom CTrieda ) Povedzme si niečo o tom, ako si naplánovať knižnicu triedy. Zatiaľ máme jednu triedu CSkola. Tá môže obsahovať funkcie i dáta. Medzi dátami môže byť pokojne i nejaká iná (no i tá istá) trieda. Aby sa návrh takejto triedy zjednodušil, pomáhame si grafickými návrhmi. Existujú dokonca programy, ktoré nám tieto návrhy pomáhajú zostrojiť. Má to i meno: Unified Modeling Language alebo UML je v softvérovom inžinierstve grafický jazyk na vizualizáciu, špecifikáciu, navrhovanie a dokumentáciu programových systémov. Ak si niekedy nájdete čas, môžete sa na nich pozrieť. Niektoré sú pre profesionálov ( a teda za peniaze), niektoré sú free, napríklad tu som použil Visual Paradigm: Takto by vyzerali naše dve triedy: V hornom riadku je meno triedy. V strednom sú dáta spolu s ich typmi (ak sú zadané, tak i s default hodnotami), dole sú funkcie. Zatiaľ si vystačíme len s týmito funkciami. Je tu niečo zvláštne. Vyzerá to akoby mali tieto dve triedy rovnaké funkcie. To však nie je pravda. Dokonca nemajú rovnaké ani mená (hoci to tak vyzerá). Ak totiž použijem ich celé mená tak funkcia ZadajMenaTriedy() v triede CSkola sa plným menom volá CSkola:: ZadajMenaTriedy() A v triede CTrieda sa volá: CTrieda:: ZadajMenaTriedy() (Ak ste projekt otvorili ako Empty Project, stačí na meno funkcie nabehnúť kurzorom a objaví sa vám ihneď informácia o tejto funkcii aj stým, z ktorej je triedy). 10

Takto vyzerajú naše triedy: Triedy v C++ CSkola.cpp #include "CSkola.h" int main(void) // CSkola skola[3] = CSkola("Orange",3),CSkola("Javorka",3),CSkola("Strojarka",3); CSkola skola[2] = CSkola("Orange",2),CSkola("Javorka",2); for(int i = 0; i < 2; i++) skola[i].zadajmenatriedy(); for(int i = 0; i < 2; i++) skola[i].zadajpocetziakov(); for(int i = 0; i < 2; i++) skola[i].zadajmenaziakov(); system("pause"); return 0; #include "CTrieda.h" CSkola.h class CSkola //Funkcie CSkola(void); //konstruktor CSkola(string smenosk); //konstruktor CSkola(string smenosk, int npocettr); //konstruktor ~CSkola(void); //destruktor void ZadajMenaTriedy(void); void ZadajMenaZiakov(void); void ZadajPocetZiakov(void); //Data private: int npocettried; string smenoskoly; CTrieda trieda[4]; ; 11

CTrieda.cpp #include "CTrieda.h" CTrieda::CTrieda(void) //konstruktor triedy univerzal npocetziakov = 20; smenotriedy = "Neznama"; CTrieda::~CTrieda(void) void CTrieda::ZadajMenaTriedy(void) cout << " Zadaj meno triedy zo skoly " << "????" << endl; cin >> smenotriedy; void CTrieda::ZadajPocetZiakov(void) cout << " Zadaj pocet ziakov v triede " << smenotriedy << " zo skoly " << "????" << endl; cin >> npocetziakov; void CTrieda::ZadajMenaZiakov(void) for(int i = 0; i < npocetziakov; i++) ziak[i].zadajmenaziakov(); CTrieda.h #include "CZiak.h" class CTrieda //Funkcie CTrieda(void); //konstruktor CTrieda(string smenotriedy); //konstruktor CTrieda(string smenotriedy, int npocetziakoch); //konstruktor ~CTrieda(void); //destruktor void ZadajMenaTriedy(void); void ZadajPocetZiakov(void); void ZadajMenaZiakov(void); //Data private: int npocetziakov; string smenotriedy; CZiak ziak[5]; ; 12

A ich využitie v main,cpp je takéto: main.cpp #include "CSkola.h" int main(void) CSkola skola[2] = CSkola("Orange",2),CSkola("Javorka",2); for(int i = 0; i < 2; i++) skola[i].zadajmenatriedy(); for(int i = 0; i < 2; i++) skola[i].zadajpocetziakov(); for(int i = 0; i < 2; i++) skola[i].zadajmenaziakov(); system("pause"); return 0; Ako to funguje? Ak chcem zadať meno triedy (školskej ), mohol by som to urobiť priamo vo funkcii v triede CSkola: for(int i = 0; i < npocetskol; i++) for(int j = 0; j < npocettried; j++) skola[i].trieda[j].zadajmenatriedy(); Alebo dokonca: for(int i = 0; i < npocetskol; i++) for(int j = 0; j < npocettried; j++) cin >> skola[i].trieda[j].smenotriedy; Čo by nakoniec pri zadávaní známky z predmetu žiakovi vyzeralo takto: for(int i = 0; i < npocetskol; i++) for(int j = 0; j < npocettried; j++) for(int k = 0; k < npocetziakov; k++) for(int l = 0; l < npocetpredmetov; l++) cin >> skola[i].trieda[j].ziak[k].predmet[l].nznamka; Ako to vyzerá? Radšej nechajme každú triedu, nech sa stará len o svoje dáta (tie potom môžu byť pokojne deklarované ako private). Znamená to, že v main.cpp zavoláme len funkciu triedy CSkola (v cykle toľkokrát, koľko máme škôl). main.cpp: for(int i = 0; i < 2; i++) skola[i].zadajmenatriedy(); 13

Táto funkcia CSkola:: ZadajMenaTriedy() vo svojom vnútri potom zavolá funkciu triedy CTrieda (toľkokrát, koľko máme tried): CSkola.cpp void CSkola::ZadajMenaTriedy(void) for(int i = 0; i < npocettried; i++) trieda[i].zadajmenatriedy(); A až funkcia CTrieda:: ZadajMenaTriedy() : CTrieda.cpp void CTrieda::ZadajMenaTriedy(void) cout << " Zadaj meno triedy zo skoly " << "????" << endl; cin >> smenotriedy; Si do svojej členskej premennej smenotriedy načíta meno školskej triedy. Aj toto sa dá znázorniť graficky (požijeme na to tzv. sekvenčný diagram Tento diagram nám hovorí, že užívateľ (main.cpp) najprv vytvorí objekt CSkola skola, ten pri svojom vzniku okamžite vytvorí pomocou konštruktora objekty CTrieda trieda. Ďalší krok je v cykle (loop) pre každú školu vytvoriť niekoľko tried. V ďalšom kroku sa v cykle pre každú školu zavolá jej funkcia CSkola:: ZadajMenaTriedy() a tá zasa zavolá v cykle funkcie CTrieda:: ZadajMenaTriedy(). 14

Zatiaľ to funguje, ale má to jednu chybičku: Jednoducho vo vnútri triedy nepoznáte meno školy, ktorej tá trieda patrí. Ako to riešiť? Opäť existuje viacero riešení. Ukážeme si dve najjednoduchšie: Môžeme meno školy poslať do funkcie CTrieda:: ZadajMenaTriedy(string smenosk) ako parameter (argument) funkcie: CSkola.cpp void CSkola::ZadajMenaTriedy(void) for(int i = 0; i < npocettried; i++) trieda[i].zadajmenatriedy(smenoskoly); CTrieda.cpp void CTrieda::ZadajMenaTriedy(string smenosk) cout << " Zadaj meno triedy zo skoly " << smenosk << endl; cin >> smenotriedy; Ako vidíte, toto by sme museli urobiť aj v ďalších funkciách triedy CTrieda. Navyše by bolo dobré zadať aj poradové číslo triedy. Skúsme ďalšie riešenie: Trieda CTrieda obsahuje tieto členské dáta: private: int npocetziakov; string smenotriedy; Prečo by nemohla obsahovať ďalšie premenné : private: 15

int npocetziakov; string smenotriedy; string smenoskoly; //meno školy, do ktorej trieda patri int nporadietriedy; //poradove cislo triedy vo svojej skole Tieto premenné by sme naplnili (definovali) hneď v konštruktore triedy a máme tieto údaje hocikedy v rámci každého objektu (školskej triedy) k dispozícii. Vytvorme teda ďalší konštruktor pre triedu CTrieda pozmeňme i konštruktor triedy CSkola, aby sme mohli hneď naplniť tieto premenné, deklarujme príslušné premenné a máme postarané: CTrieda.cpp: CTrieda::CTrieda(string smenosk, int nporadie) //konstruktor triedy so zadanim skoly a poradia triedy smenoskoly = smenosk; nporadietriedy = nporadie; CSkola.cpp: CSkola::CSkola(string smenosk, int npocettr) //konstruktor triedy univerzal //cout << "konstruktor triedy s menom a poctom " << endl; npocettried = npocettr; smenoskoly = smenosk; for(int i = 0; i < npocettried; i++) trieda[i] = CTrieda(sMenoSkoly, i); //zavoláme konstruktor triedy CTrieda A odteraz máme k týmto údajom stály prístup. Každá školská trieda bude vždy vedieť, ktorej škole patrí a ktorá je v tejto škole v poradí. (Ostatne v každej triednej knihe to je napísané). Poďme ďalej: 4. Ďalšia vnorená trieda CZiak V triedach bývajú žiaci. Vytvorme novú triedu CZiak, aby sme vo vnútri CTrieda mohli zaviesť pole objektov CZiak ziak[5]; Znovu vytvorme aj konštruktor do ktorého môžeme zaviesť aj meno triedy, z ktorej žiak je, aj meno školy a aj poradové číslo žiaka v triede. Problém ale bude kedy tento konštruktor zavolať? V konštruktore CTrieda to nie je možné, tam ešte nepoznáme počet žiakov, ani meno triedy. Dá sa to urobiť hneď potom, ako tieto údaje budeme vedieť a to je vo funkcii, kde načítavame počet žiakov v triede CTrieda. Takže aj túto musíme trochu prerobiť výsledkom bude: 16

CZiak.h: #include <iostream> #include <string> using namespace std; class CZiak //Funkcie CZiak(void); //konstruktor CZiak(string smenosk, string smenotr, int nporadie); //konstruktor v ktorom zadame meno triedy, skoly a poradove cislo ziaka ~CZiak(void); //destruktor void ZadajMenaZiakov(void); //Data private: string smenoziaka; string smenoskoly; //meno školy, do ktorej trieda patri string smenotriedy; //meno školy, do ktorej trieda patri int nporadieziaka; //poradove cislo ziaka vo svojej triede ; CZiak.cpp: #include "CZiak.h" CZiak::CZiak(void) //konstruktor triedy univerzal CZiak::CZiak(string smenosk, string smenotr, int nporadie) //konstruktor v ktorom zadame meno triedy, skoly a poradove cislo ziaka smenoskoly = smenosk; smenotriedy = smenotr; nporadieziaka = nporadie; CZiak::~CZiak(void) //destruktor triedy univerzal //cout << "destruktor triedy zakladny " << smeno << endl; void CZiak::ZadajMenaZiakov(void) cout << " Zadaj meno ziaka c." << nporadieziaka << " Z triedy " << smenotriedy << " Zo skoly " << smenoskoly << endl; cin >> smenoziaka; CTrieda.cpp: void CTrieda::ZadajPocetZiakov(void) cout << " Zadaj pocet ziakov v triede " << smenotriedy << " zo skoly " << smenoskoly << endl; cin >> npocetziakov; for(int i = 0; i < npocetziakov; i++) ziak[i] = CZiak(sMenoSkoly, smenotriedy, i); 17

Myslím, že toto hravo zvládnete. Ak nie posielam kód. Úlohy: 1. Najprv si rozbehnite projekt do tohto bodu pekne podľa popisu v tomto texte. Pozorne so pozrite ktorá funkcia volá ktorú. Keď sa s týmto pohráte a prídete na to ako to funguje, máte vyhrané. 2. Potom určite nebude problémom doplniť program o ďalšiu triedu CPredmet s premennými a funkciami vyznačenými v diagrame. Je to o to ľahšie, že počet predmetov je daný 2, ako i mená Fyzika, Informatika. Tieto údaje môžete naplniť hneď v konštruktore a použiť ho podobne ako u škôl. Napríklad v konštruktore triedy CZiak. Každý predmet bude mať pole int nznamka[2], ktoré môžu mať na začiatku hodnotu napríklad -1 aby sme vedeli, že známky ešte neboli zadané a premennú int nzadaneznamky, ktorá má na začiatku hodnotu 0. A jedinú funkciu void ZadajteZnamku(void) v ktorej budete tieto známky zadávať pre všetky školy, triedy a žiakov. Teda takéto funkcie musia mať i všetky predchádzajúce triedy CSkola, CTrieda, CZiak. Pozri diagram: 18

19

5. Príklad Zoo V tomto príklade sme vytvorili malú zoo s troma mačkami. Každá z mačiek bude objektom triedy CMacka. Vo funkcii main() vytvoríme pole troch maciek do ktorých hneď v konštruktori zadáme meno každej mačky. int main(void) CMacka macicka[3] = "Liza", "Micka", "Usko"; Tento konštruktor v triede CMacka vyzerá nejako takto: //IB: vyuzijeme konstruktor so zadavanim mien CMacka::CMacka(string smenomacky) smeno = smenomacky; //IB: konstruktor so zadanim mena macky smeno je private členská premenná triedy CMacka a práve v konštruktore ju naplníme pomocou vstupu (parametru, argumentu: string smenomacky). Funguje to tak, že v momente ak vykonáme deklaráciu objektov: CMacka macicka[3] = "Liza", "Micka", "Usko"; Zavoláme vlastne trikrát za sebou konštruktor triedy CMacka. Čo znamená že pre macicku[0] je konštruktor niečo ako: CMacka::CMacka(string smenomacky = "Liza") smeno = smenomacky (čo je vlastne "Liza"); //IB: konstruktor so zadanim mena macky Premenná smenomacky neexistuje predtým ako tento konštruktor zavoláme. Akonáhle ho zavoláme ( CMacka macicka[3] = "Liza", "Micka", "Usko";) vznikne lokálna (existuje len vo vnútri konštruktora) premenná string smenomacky a hneď sa naplní (skopíruje sa do nej) obsah "Liza". Príkazom : smeno = smenomacky; sa tento obsah ("Liza") priradí do členskej premennej smeno triedy CMacka. Po skončení funkcie konštruktor jej lokálna premenná string smenomacky okamžite zanikne, ale členská premenná smeno už bude mať stále (až kým ju nezmeníme) hodnotu "Liza". Potom sa zavolá druhý konštruktor s menom "Micka" a teda vznikne druhý objekt (macicka[1]) a nakoniec macicka[1] ("Usko") a to všetko v jednom riadku : CMacka macicka[3] = "Liza", "Micka", "Usko"; V ďalšom kroku vo funkcii main zadám jednotlivým objektom mačkám farbu a nakoniec ich farby vypíšeme. To všetko vykonávame v cykle pre index pola macicka[i] od 0 po 2. Vytvoríme novú triedu CNoha a v triede CMacka zadeklarujem 4 objekty noha ako pole: #include "CNoha.h" class CMacka 20

CMacka(void); //Konstruktor CMacka(string smenomacky); //Konstruktor so zadanim mien ~CMacka(void); //Destruktor void ZadajMeno(void); void NapisMeno(void); void ZadajFarbu(void); void NapisFarbu(void); int CelkovyPocetPazurov(void);//pre jednu macku CNoha noha[4]; private: string sfarba; string smeno; ; Pre každú nohu vytvoríme členskú premennú triedy CNoha class CNoha CNoha(void); //Konstruktor ~CNoha(void); //Destruktor int CelkovyPocetPazurov(void);//pre jednu nohu private: int npocetpazurov; ; npocetpazurov nastavíme hneď v konštruktore na hodnotu 5. Naša úloha je spočítať všetky pazúry všetkých mačiek v našej zoo. Prikladám hotové súbory s poznámkami, ako jednotlivé funkcie pracujú. V main() v cykle zavoláme funkciu macicka[i].celkovypocetpazurov(). Jedna takáto funkcia pre každý index i od 0 po 2 nám vráti počet pazúrov, ktoré má dokopy jedna mačka. Teda ak postupne budeme tieto hodnoty sčítavať, dostaneme výsledný súčet. (Pozor: skutočné meno tejto funkcie je CMacka::CelkovyPocetPazurov(). A to sa dá iba tak, že vo vnútri tejto funkcie sa 4 krát zavolá funkcia noha[i]. CelkovyPocetPazurov() s celým menom CNoha::CelkovyPocetPazurov().Každá táto funkcia nám vráti počet pazúrov na jednej nohe. Keď budem postupne sčítavať každú nohu, získam počet pazúrov celej mačky. (Pozri vysvetlivky v kóde.) Teraz keď vieme ako spočítať jednotlivé pazúry všetkých mačiek, nebude pre nás problémom spočítať počet žiakov vo všetkých školách, vo všetkých triedach v našom predchádzajúcom projekte.: Úloha. Vytvorte pole z troch objektov triedy CMacka. Tá obsahuje vlastnosti : smeno (String) a pole štyroch objektov triedy CLabka. Táto trieda obsahuje počet pazúrov (Integer). Spočítajte pazúriky všetkých mačiek pomocou funkcií týchto tried 21

22