2. díl - První objektová aplikace v C++

C a C++ C++ Objektově orientované programování První objektová aplikace v C++

ONEbit hosting Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

Na začátku sekce se základními strukturami jazyka C++ jsme si vytvořili program Hello world. Udělejme si nyní podobný program jako úvod do objektově orientovaného programování. Naprogramujme si Hello object world!

Nejprve si vytvoříme nový projekt (konzolovou aplikaci). Vytvoříme soubor Source.cpp, do kterého si můžeme napsat nějaký základ kódu:

#include <conio.h>
#include <windows.h>
#include <locale>

int main(void)
{
        //nastavíme české kódování(podpora diakritiky v konzoli)
        std::locale loc("Czech_Czech Republic.1250");
        std::locale::global(loc);
        //nastavíme titulek okna
        SetConsoleTitleA("Hello object world!");

        return 0;
}

V Solution Exploreru napravo klikneme pravým tlačítkem myši na složku Source files a vybereme Add -> Class.

Přidání C++ třídy ve Visual Studio

V okně, které se nám zobrazí, rozklikneme C++ Class. Pak se zobrazí další okno, ve kterém vyplníme údaje podle obrázku:

Přidání C++ třídy ve Visual Studio

Visual studio nám vytvoří dva soubory: zdravic.h (tam bude samotná třída) a zdravic.cpp (kde budou definice funkcí). Ty vypadají takto:

//zdravic.h
#pragma once
class zdravic
{
public:
        zdravic(void);
        ~zdravic(void);
};
//zdravic.cpp
#include "zdravic.h"

zdravic::zdravic(void)
{
}

zdravic::~zdravic(void)
{
}

#pragma once zajišťuje, že bude soubor čten jen jednou zdravic(void) a ~zdravic(void) jsou tzv. konstruktor a destruktor. Konstruktor se spustí při vytvoření instance třídy, destruktor ve chvíli, kdy na ni ztratíme referenci. Až budeme tuto třídu používat, budeme chtít, aby něco uměla. Kvůli tomu si třídu zdravic rozšíříme o nějakou metodu. Ta se v C++ zapisuje stejně jako funkce:

//zdravic.h
#pragma once
class zdravic
{
public:
        void pozdrav();
        zdravic(void);
        ~zdravic(void);
};
//zdravic.cpp
#include <iostream>
using namespace std;
#include "zdravic.h"

zdravic::zdravic(void)
{
}

zdravic::~zdravic(void)
{
}

void zdravic::pozdrav(void)
{
        cout << "Hello object world!";
}

Zde jsme prozatím skončili, přejdeme do Source.cpp.

Nyní si v těle metody Main vytvoříme instanci třídy zdravic. Bude to tedy ten objekt zdravič, se kterým budeme pracovat. Objekty se ukládají do proměnných, název třídy slouží jako datový typ. Instance můžeme pojmenovat jakkoliv, já doporučuji, aby v názvu byl "schovaný" název třídy. Deklarujme si tedy proměnnou a následně v ní založme novou instanci třídy zdravic:

zdravic _zdravic;

Tím se vytvoří proměnná _zdravic a zavolá se konstruktor třídy zdravic - zdravic(void). Instanci můžeme vytvořit i takto:

zdravic* _zdravic = new zdravic();

Tento způsob vytvoří instanci dynamicky. Vrátíme se k němu v pozdějších dílech seriálu.

A protože už máme vytvořený svůj první objekt (instanci), můžeme zavolat jeho metodu. Na konec kódu (před return 0;) ještě doplníme _getch();(funkce ze souboru conio.h, aby program hned neskončil a čekal na stisk libovolné klávesy). Soubor Source.cpp tedy vypadá takto:

#include "zdravic.h"
#include <conio.h>
#include <windows.h>
#include <locale>

int main(void)
{
        //nastavíme české kódování(podpora diakritiky v konzoli)
        std::locale loc("Czech_Czech Republic.1250");
        std::locale::global(loc);
        //nastavíme titulek okna
        SetConsoleTitleA("Hello object world!");

        zdravic _zdravic;
        _zdravic.pozdrav();

        _getch();
        return 0;
}

Teď můžeme program spustit.

První objektová aplikace v C++

Máme tedy svou první objektovou aplikaci!

Dejme nyní naší metodě Pozdrav() parametr jmeno, aby dokázala pozdravit konkrétního uživatele:

//zdravic.h
void pozdrav(string jmeno);
//zdravic.cpp
void zdravic::pozdrav(string jmeno)
{
        cout << "Ahoj uživateli " << jmeno.c_str() << endl;
}

Nyní upravíme naši metodu Main:

zdravic _zdravic;
_zdravic.pozdrav("Karel");
_zdravic.pozdrav("Petr");
_getch();
Metoda s parametrem v C++

Třídě nyní přidáme nějakou datovou složku, nabízí se text, kde bude uložen text pozdravu. Datové složky (atributy) se definují stejně, jako proměnné. Upravme tedy naši třídu:

//zdravic.h
class zdravic
{
public:
        string text;
        void pozdrav(string jmeno);
        zdravic(void);
        ~zdravic(void);
};
//zdravic.cpp
void zdravic::pozdrav(string jmeno)
{
        cout << text.c_str() << ' ' << jmeno.c_str() << '!' << endl;
}

Text nyní musíme pochopitelně nastavit vytvořené instanci v Source.cpp:

zdravic _zdravic;
_zdravic.text = "Ahoj uživateli";
_zdravic.pozdrav("Karel");
_zdravic.pozdrav("Petr");
_zdravic.text = "Vítam tě tu programátore";
_zdravic.pozdrav("Richard");
Atributy v C++

Vzhledem k objektovému návrhu není nejvhodnější, aby si každý objekt ovlivňoval vstup a výstup, jak se mu zachce. Pochopitelně narážím na naše vypisování do konzole. Každý objekt by měl mít určitou kompetenci a tu by neměl překračovat. Pověřme náš objekt pouze sestavením pozdravu a jeho výpis si zpracujeme již mimo, v našem případě v metodě Main. Výhodou takto navrženého objektu je vysoká univerzálnost a znovupoužitelnost. Objekt doposud umí jen psát do konzole, my ho však přizpůsobíme tak, aby daná metoda text pouze vracela a bylo na jeho příjemci, jak s ním naloží. Takto můžeme pozdravy ukládat do souborů, psát na webové stránky nebo dále zpracovávat.

Jelikož chceme, aby metoda vracela hodnotu a to string, změníme její dosavadní typ void na string. K návratu hodnoty použijeme příkaz return. Upravme kód třídy:

//zdravic.h
#pragma once
#include <iostream>
using namespace std;

class zdravic
{
public:
        string pozdrav(string jmeno);
        zdravic(void);
        ~zdravic(void);
        string text;
};
//zdravic.cpp
#include "zdravic.h"

zdravic::zdravic(void){}

zdravic::~zdravic(void){}

string zdravic::pozdrav(string jmeno)
{
        string str = text;
        str += ' ';
        str += jmeno;
        str += "!\n";
        return str;
}

K tomu musíme upravit soubor Source.cpp:

#include "zdravic.h"
#include <conio.h>
#include <windows.h>
#include <iostream>
#include <locale>
using namespace std;

int main(void)
{
        locale loc("Czech_Czech Republic.1250");
        locale::global(loc);
        SetConsoleTitleA("Hello object world!");

        zdravic _zdravic;
        _zdravic.text = "Ahoj uživateli";
        cout << _zdravic.pozdrav("Karel");
        cout << _zdravic.pozdrav("Petr");
        _zdravic.text = "Vítám tě tu programátore";
        cout << _zdravic.pozdrav("Richard");

        _getch();
        return 0;
}

Nyní je náš kód dle dobrých praktik. Ještě naši třídu okomentujme, jak se sluší a patří. Komentáře budeme psát nad název třídy a nad název každého atributu a metody. K jejich zápisu použijeme trojlomítko "///". Vyplatí se nám to ve chvíli, když na třídě používáme nějakou metodu, její popis se nám zobrazí v našeptávači. Zdokumentovaná třída může vypadat např. takto:

#pragma once
#include <iostream>
using namespace std;

/// Třída reprezentuje zdravič, který slouží ke zdravení uživatelů
class zdravic
{
public:
        /// Text pozdravu
        string text;
        /// Pozdraví uživatele textem pozdravu a jeho jménem
        string pozdrav(string jmeno);
        zdravic(void);
        ~zdravic(void);
};

Podíváme se, že nám VS opravdu popisky zobrazí:

Visual Studio zobrazující C++ dokumentaci

A jsme u konce. Námi napsaný program má již nějakou úroveň, i když vlastně nic nedělá. Za úkol máte předělat si naši konzolovou kalkulačku do objektů. Příště si uděláme takovou jednoduchou hříčku, necháme dva objekty (bojovníky) soupeřit v aréně (také objektu). Máte se na co těšit ;-)


 

Stáhnout

Staženo 374x (19.9 MB)
Aplikace je včetně zdrojových kódů v jazyce C++

 

 

Článek pro vás napsal Zdeněk Pavlátka
Avatar
Jak se ti líbí článek?
10 hlasů
Autor se věnuje spoustě zajímavých věcí :)
Aktivity (3)

 

 

Komentáře
Zobrazit starší komentáře (30)

Avatar
Filip Šohajek
Redaktor
Avatar
Filip Šohajek:10.2.2016 22:26

Toto je pravda, jakmile odejde ze scopu, zavolá se jeho destruktor.

 
Odpovědět 10.2.2016 22:26
Avatar
Polymath
Člen
Avatar
Polymath:11.2.2016 14:56

Platí to pro instance na zásobníku. A destruktor se volat nedá, provede se automaticky při rušení objektu, k čemuž pro instance na haldě slouží delete.

 
Odpovědět 11.2.2016 14:56
Avatar
Emilia T
Člen
Avatar
Emilia T:11.2.2016 18:25

mozno som sa nevyjadrila dostatocne presne, destruktor sa vola vtedy ked je objekt "destroyed (deallocated)". nie vtedy ked nan stratime referenciu. Pokial je objekt vytvoreny dynamickym alokovanim pamate, je potrebne pamat dealokovat teda zavolat na prislusny objekt delete operator.

https://msdn.microsoft.com/…t4fe76c.aspx

 
Odpovědět 11.2.2016 18:25
Avatar
Emilia T
Člen
Avatar
Odpovídá na Emilia T
Emilia T:11.2.2016 18:38

neviem prist na to ako sa tu upravuju komentare... namiesto vety "nie vtedy ked nan stratime referenciu" malo byt "neda sa vo vseobecnosti povedat ze to nastane vtedy ked nan stratime referenciu"

 
Odpovědět 11.2.2016 18:38
Avatar
Libor Šimo (libcosenior):21.12.2016 12:16

Môže mi niekto vysvetliť prečo sa v článku používa

jmeno.c_str()

a nie len

jmeno
Odpovědět 21.12.2016 12:16
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Zdeněk Pavlátka
Tým ITnetwork
Avatar
Odpovídá na Libor Šimo (libcosenior)
Zdeněk Pavlátka:21.12.2016 15:30

Protože cout neumí pracovat s typem string. c_str vrací ukazatel na pole znaků a to už cout vypsat umí.

Odpovědět  +1 21.12.2016 15:30
Kolik jazyků umíš, tolikrát jsi programátor.
Avatar
Odpovídá na Zdeněk Pavlátka
Lukáš Hruda (Luckin):21.12.2016 20:57

Nevím kde jsi na to přišel, ale std::cout umí normálně vypisovat objekty třídy std::string. Pokud ti to nejde, tak nejspíš používáš nějaký exotický překladač.

 
Odpovědět  +1 21.12.2016 20:57
Avatar
Zdeněk Pavlátka
Tým ITnetwork
Avatar
Odpovídá na Lukáš Hruda (Luckin)
Zdeněk Pavlátka:21.12.2016 22:46

Když jsem psal ten článek, tak mi to z nějakého důvodu nešlo. Od té doby jsem string v C++ nepoužíval.

Odpovědět 21.12.2016 22:46
Kolik jazyků umíš, tolikrát jsi programátor.
Avatar
Odpovídá na Zdeněk Pavlátka
Lukáš Hruda (Luckin):22.12.2016 9:10

To znám. Už se mi párkrát stalo, že jsem v nějakém jazyce použil nějakou konstrukci a nefungovala mi, protože jsem tam nejspíš měl chybu a pak jsem si hrozně dlouho myslel, že to nejde a třeba až za pár měsíců jsem zjistil, že to jde :D Mimochodem string bych doporučil používat, ušetříš ti tím spoustu práce, obzvlášť v C++11 a novějším.

 
Odpovědět 22.12.2016 9:10
Avatar
Zdeněk Pavlátka
Tým ITnetwork
Avatar
Odpovídá na Lukáš Hruda (Luckin)
Zdeněk Pavlátka:22.12.2016 9:25

já používám C++ jen na domácí úkoly a tam vůbec nepotřebuji pracovat s textem... ;) (a několik let jsem ho nepoužíval vůbec)

Odpovědět 22.12.2016 9:25
Kolik jazyků umíš, tolikrát jsi programátor.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 40. Zobrazit vše