2. diel - Prvý objektová aplikácie v C ++
Na začiatku kurzu so základnými štruktúrami jazyka C ++ sme si vytvorili program Hello world. Urobme si teraz podobný program ako úvod do objektovo orientovaného programovania. Naprogramujte si Hello object world!
Vytvorenie projektu
Najprv si vytvoríme nový projekt. Postup vytvorenia projektu môžete vidieť na screenshotoch nižšie.
Projekt založíme ako klasický prázdny (Empty) C ++ projekt. Následne klikneme na OK.
V projekte si vytvoríme nový súbor main.cpp, čo urobíme kliknutím pravým tlačidlom na projekt v Solution Exploreru -> Add -> New Item.
Následne vyberieme .cpp súbor.
Do tohto súboru vložíme základnú štruktúru aplikácie v C ++ ako sme boli zvyknutí doteraz:
#include <iostream> using namespace std; int main() { return 0; }
V Solution Exploreri klikneme pravým tlačidlom myši na priečinok Source files a vyberieme Add -> Class.
V okne, ktoré sa nám zobrazí, rozkliknite C ++ Class. Potom sa zobrazí ďalšie okno, v ktorom vyplníme údaje podľa obrázka. Ide o definíciu názvu súborov triedy, ktorá bude reprezentovať vzor pre objekt, ktorý vie pozdraviť:
Visual štúdio nám vytvoria dva súbory: Zdravic.h (tam bude samotná trieda) a Zdravic.cpp (kde budú definície funkcií). Rozdelenie triedy do týchto dvoch súborov je nutné - viď lekcie o kompiláciu v C a C ++. Obsah súborov prepíšeme do nasledujúcej podoby:
Zdravic.h
#ifndef __ZDRAVIC_H__ #define __ZDRAVIC_H__ class Zdravic { }; #endif
Zdravic.cpp
#include "Zdravic.h"
Preprocesové direktívy (#ifndef
, #define
a
#endif
) zaisťujú, že bude súbor includován len raz. Visual
Studio v predvolenom nastavení používa #pragma once
direktívu,
ale nami ukázaná je praktickejšie (funguje aj pri kompilácii na Linux).
Pôvodne vygenerované funkcie Zdravic(void)
a
~Zdravic(void)
boli tzv. Konštruktor a deštruktor, na ktoré sa
pozrieme až v nasledujúcej lekcii.
Deklarácia metódy
Až budeme túto triedu používať, budeme chcieť, aby niečo vedela. Kvôli tomu si triedu Zdravice rozšírime o nejakú metódu. Tá sa v C ++ zapisuje rovnako ako funkcia:
Zdravic.h
#ifndef __ZDRAVIC_H__ #define __ZDRAVIC_H__ class Zdravic { public: void pozdrav(); }; #endif
Zdravic.cpp
#include <iostream> #include "Zdravic.h" using namespace std; void Zdravic::pozdrav(void) { cout << "Hello object world!"; }
Metódu musíme deklarovať 2x, raz ako hlavičku do .h súboru a raz aj s telom do .cpp súboru. Tu sme zatiaľ skončili, prejdeme do main.cpp.
Vytvorenie inštancie triedy
Teraz si v tele metódy main()
vytvoríme inštanciu triedy
Zdravice. Najskôr ale musíme povedať, že chceme používať našu triedu
Zdravic
, ktorú sme si pred chvíľou vytvorili. To vykonáme
naincludováním našej triedy do súboru main.cpp
pomocou
#include "Zdravic.h"
. Na rozdiel od klasických include (napríklad
iostream) si môžete všimnúť nahradenie ostrých zátvoriek za
úvodzovky. Ak použijeme hranaté zátvorky, kompilátor hľadá súbor vo
svojich cestách (spravidla cesty ku knižniciam). Ak použijeme úvodzovky,
kompilátor použije relatívnu cestu (v našom prípade aktuálny projekt).
Objekty sa ukladajú do premenných, názov triedy slúži ako dátový typ
(ako je tomu napríklad u int), inštancia môžeme pomenovať akokoľvek.
Vyhlásiť si premennú a následne v nej založme novú inštanciu triedy
Zdravic
:
#include <iostream> #include "Zdravic.h" using namespace std; int main() { Zdravic _zdravic; return 0; }
Tým sa vytvorí premenná _zdravic
. Inštanciu môžeme
vytvoriť aj takto:
Zdravic* _zdravic = new Zdravic();
Tento spôsob vytvorí inštanciu dynamicky na halde. Vrátime sa k nemu v pokročilejších dieloch nášho C ++ kurzu.
Volanie metódy
A pretože už máme vytvorený svoj prvý objekt (inštanciu), môžeme
zavolať jeho metódu. Na koniec kódu (pred return 0;
) ešte
doplníme cin.get()
(aby program hneď neskončil a čakal na
stlačenie ľubovoľného klávesu). Súbor main.cpp vyzerá vo finále
takto:
Main.cpp
#include <iostream> #include "Zdravic.h" using namespace std; int main() { Zdravic _zdravic; _zdravic.pozdrav(); cin.get(); return 0; }
Teraz môžeme program spustiť. Výstup bude nasledujúci:
Konzolová aplikácia
Hello object world!
Máme teda svoju prvú objektovú aplikáciu! Logiku vykonáva príslušný objekt. Až budeme písať väčšie aplikácie, rozdelenie funkcií do jednotlivých objektov veľmi oceníme kvôli prehľadnosti.
Parametre metódy
Dajme teraz našej metóde pozdrav()
parameter jmeno,
aby dokázala pozdraviť konkrétneho užívateľa:
Zdravic.h
#ifndef __ZDRAVIC_H__ #define __ZDRAVIC_H__ #include <string> using namespace std; class Zdravic { public: void pozdrav(string jmeno); }; #endif
Zdravic.cpp
#include <iostream> #include "Zdravic.h" using namespace std; void Zdravic::pozdrav(string jmeno) { cout << "Ahoj uzivateli " << jmeno << endl; }
Teraz upravíme našu funkciu main()
:
Zdravic _zdravic; _zdravic.pozdrav("Karel"); _zdravic.pozdrav("Petr");
A po spustení aplikácie získame nasledujúci výstup:
Konzolová aplikácia
Ahoj uzivateli Karel
Ahoj uzivateli Petr
Atribúty triedy
Triede teraz pridáme nejaké dáta ( "premennú"), kde bude uložený text pozdravu. Z minulej lekcie už vieme, že triedy obsahujú funkcionalitu a dáta. Funkciu už máme, ukážme si teda ako sa do objektov ukladajú dáta. Dátové zložky triedy (atribúty) sa definujú rovnako ako premenné. Upravme teda našu triedu:
Zdravic.h
Atribút (premennú) deklarujeme v hlavičkovom súbore:
class Zdravic { public: string text; void pozdrav(string jmeno); };
Teraz si všetky inštancie triedy Zdravice ukladajú svoj text.
Zdravic.cpp
Upravme metódu pozdrav()
tak, aby ku zdravenie používala text
v atribúte text
:
void Zdravic::pozdrav(string jmeno) { cout << text << " " << jmeno << endl; }
Main.cpp
Text teraz musíme prvýkrát nastaviť vytvorené inštanciu v main.cpp:
Zdravic _zdravic; _zdravic.text = "Ahoj uzivateli"; _zdravic.pozdrav("Karel"); _zdravic.pozdrav("Petr"); _zdravic.text = "Vitam te tu programatore"; _zdravic.pozdrav("Richard");
A výstup aplikácie:
Konzolová aplikácia
Ahoj uzivateli Karel
Ahoj uzivateli Petr
Vitam te tu programatore Richard
Návratová hodnota metódy
Vzhľadom k objektovému návrhu nie je najvhodnejšie, aby každý objekt
ovplyvňoval vstup a výstup. Pochopiteľne narážam na naše vypisovanie do
konzoly. Každý objekt by mal mať určitú kompetencii (zodpovednosť) a tú
by nemal prekračovať. Povera náš objekt iba zostavením pozdravu a jeho
výpis si spracujeme niekde inde, v našom prípade v metóde
main()
. Výhodou takto navrhnutého objektu je vysoká
univerzálnosť a znovupoužitelnost. Objekt doposiaľ vie len písať do
konzoly, my ho však prispôsobíme tak, aby daná metóda text iba vracala a
bolo na jeho príjemcovi, ako s ním naloží. Takto môžeme pozdravy ukladať
do súborov, vypísať na formulár alebo ďalej spracovávať.
Keďže chceme, aby metóda vracala hodnotu typu string
,
zmeníme jej doterajší typ void
na string
. K
návratu hodnoty použijeme príkaz return
. Upravme kód
triedy:
Zdravic.h
class Zdravic { public: string text; string pozdrav(string jmeno); };
Zdravic.cpp
A rovnako tak aj implementáciu:
string Zdravic::pozdrav(string jmeno) { return text + " " + jmeno + "!\n"; }
Main.cpp
K tomu musíme upraviť súbor main.cpp:
int main() { Zdravic _zdravic; _zdravic.text = "Ahoj uzivateli"; cout << _zdravic.pozdrav("Karel"); cout << _zdravic.pozdrav("Petr"); _zdravic.text = "Vitam te tu programatore"; cout << _zdravic.pozdrav("Richard"); cin.get(); return 0; }
Teraz je náš kód podľa dobrých praktík. Zdrojové kódy sú priložené pod článkom. Celý program si môžete vyskúšať tu alebo v priloženom projektu.
#include <iostream> #include "zdravic.h" using namespace std; int main() { zdravic _zdravic; _zdravic.text = "Ahoj uzivateli"; cout << _zdravic.pozdrav("Karel"); cout << _zdravic.pozdrav("Petr"); _zdravic.text = "Vitam te tu programatore"; cout << _zdravic.pozdrav("Richard"); cin.get(); return 0; }
#include <iostream> #include "zdravic.h" using namespace std; string zdravic::pozdrav(string jmeno) { return text + " " + jmeno + "!\n"; }
#ifndef __ZDRAVIC_H__ #define __ZDRAVIC_H__ #include <string> using namespace std; class zdravic { public: string text; string pozdrav(string jmeno); }; #endif
A sme u konca. Nami napísaný program má už nejakú úroveň, aj keď vlastne nič nerobí. Za úlohu máte prerobiť si našu konzolovú kalkulačku do objektov. Nabudúce, Riešené úlohy k 1. a 2. lekciu OOP v C ++ , sa bližšie pozrieme na sľúbené konštruktory a deštruktory.
V nasledujúcom cvičení, Riešené úlohy k 1. a 2. lekciu OOP v C ++, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 162x (4.66 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C++