Image
19.6.2016 0 Comments

C++ / Štandardná knižnica C++ / 23. časť

Späť na úvod >> Späť na programovanie >> Späť na seriál

Tak, a je to tu. Dnes sa pri seriáli o strastiach a slastiach C++ stretávame naposledy. Necelé dva roky som sa snažil podeliť sa s vami o svoje vedomosti a pomôcť tak rozšíriť rady programátorov v tomto pravdepodobne najmocnejšom a súčasne najnáročnejšom jazyku (aspoň podľa môjho názoru). Či sa mi to podarilo, to musíte vedieť predovšetkým vy. Za tie dva roky som od vás dostal nespočetne veľa ohlasov, z ktorých výrazná väčšina bola pozitívna, a preto pevne verím, že seriál splnil svoj cieľ.

Skôr však, než výklad o jazyku C++ ukončíme, musíme si ešte niečo povedať o štandardnej knižnici C++. Iste tušíte, o čo ide. Tak ako bola súčasťou jazyka C určitá štandardná množina funkcií, štruktúr, typov a makier, ktoré boli (alebo aspoň mali byť) k dispozícii v každej implementácii, i v C++ si nemusíme všetko programovať sami a mnoho potrebných funkcií a vzhľadom na objektový charakter C++ predovšetkým tried a šablón dostaneme v rámci implementácie práve v podobe štandardnej knižnice C++.

Pri uvažovaní nad objemom informácií, ktoré by som vám chcel sprostredkovať v tejto časti seriálu, som bol postavený pred dilemu: na jednej strane je štandardná knižnica C++ natoľko rozsiahla a komplikovaná, že preberať ju tu podrobne nemá zmysel – napokon knižnica je dôkladne zdokumentovaná v elektronických príručkách k dostupným prekladačom, kde si nájde informácie v detailnejšom opise každý, kto ich bude potrebovať. Na druhej strane si nemôžem dovoliť jej opis úplne vynechať, pretože je to súčasť normy ANSI a patrí k C++ ako chvost k mačke. Rozhodol som sa teda pre podobný spôsob výkladu ako pri rozprávaní o knižnici jazyka C – povieme si o jednotlivých oblastiach, ktoré štandardná knižnica C++ pokrýva, o najužitočnejších funkciách či triedach z každej oblasti a prípadne o špecifikách ich použitia. Všetky ďalšie informácie už budete musieť vyhľadať sami.

Hlavičkové súbory

Kedysi dávno, na začiatku seriálu, sme si hovorili, že hlavičkové súbory v C++ majú obyčajne príponu .H, prípadne v niektorých implementáciách aj .HPP. Štandardná knižnica C++ túto konvenciu dosť radikálnym spôsobom ruší – jej hlavičkové súbory sú totiž bez prípony. Keďže C++ už nejaký čas existuje a norma ANSI bola kodifikovaná len nedávno, je možné, že v niektorých implementáciách budú k dispozícii aj verzie súborov s príponou, ale vo všeobecnosti bude vhodné zvyknúť si na nový spôsob.

Ďalšia vec, o ktorej musíme vedieť skôr, než si začneme hovoriť o štandardnej knižnici, sa týka priestorov mien. V predchádzajúcom pokračovaní sme si okrem iného povedali, že všetky deklarované mená zo štandardnej knižnice C++ sú súčasťou priestoru mien s názvom std. Ak teda chceme použiť niektorú zo štandardných funkcií či tried, buď ju explicitne kvalifikujeme ako std::identifikátor, alebo použijeme deklaráciu using s príslušným identifikátorom (using std::identifikátor;), prípadne použijeme rovno direktívu using namespace std;, čím si sprístupníme všetky identifikátory z priestoru std. Toto však platí iba v prípade, že chceme pracovať s objektom, ktorého deklarácia sa nachádza vo vloženom hlavičkovom súbore bez prípony, napríklad iostream. Ak použijeme klasický variant, teda iostream.h (samozrejme, implementácia to musí umožňovať), direktívu using nepotrebujeme použiť, lebo ju prekladač bude predpokladať implicitne za nás.

Štandardná knižnica C++ preberá niekoľko (presne 18) hlavičkových súborov známych z jazyka C. Mierne však upravuje ich názov: jednak odstraňuje príponu .H (to sa dalo čakať), jednak predraďuje pred názov znak c. Je, samozrejme, možné v programe C++ použiť hlavičkový súbor jazyka C (napríklad stdio.h), ale odporúčam vám radšej používať nový tvar (t. j. napríklad cstdio). Rozdiel medzi stdio.h a cstdio by mal byť rovnaký ako medzi iostream.h a iostream (pozri vyššie), ale napríklad vo Visual C++ 6.0 sa obidva súbory správajú rovnako.

Pre úplnosť si uveďme zoznam spomínaných osemnástich hlavičkových súborov prebratých z jazyka C: cassert, cctype, cerrno, cfloat, ciso646, climits, clocale, cmath, csetjmp, csignal, cstdarg, cstddef, cstdio, cstdlib, cstring, ctime, cwchar a cwctype. Ich obsah je prakticky totožný s ich staršími ekvivalentmi – implementované sú často tak, že obsahujú okrem bežnej „omáčky“ jedinú direktívu #include. Nebudeme si o nich hovoriť nič podrobnejšie, opakovali by sme totiž len pätnástu časť seriálu, kde sa možno dozvedieť o štandardnej knižnici jazyka C viac.

Okrem deklarácií prebratých z jazyka C obsahuje štandardná knižnica C++ mnoho nových funkcií, tried a šablón, ktorých deklarácie nájdeme v týchto hlavičkových súboroch: algorithm, bitset, complex, deque, exception, fstream, functional, iomanip, ios, iosfwd, iostream, istream, iterator, limits, list, locale, map, memory, numeric, ostream, queue, set, sstream, stack, stdexcept, streambuf, string, strstream, utility, valarray a vector. V ďalšom texte si jednotlivé súbory rozdelíme do niekoľkých oblastí.

Prúdové triedy

Hádam najdôležitejšími a najčastejšie používanými triedami zo štandardnej knižnice sú triedy na prácu s prúdmi. Už pri opisovaní štandardnej knižnice jazyka C sme si uviedli, akým mocným prostriedkom sú prúdy a čo je ich výhodou. Na zopakovanie: prúdy predstavujú generalizované zdroje či spotrebiče údajov, ktoré môžu byť napojené na diskové súbory, pomenované rúry (?!), reťazce v pamäti, klávesnicu a pod. Neoddiskutovateľnou prednosťou prúdov je jednotný spôsob prístupu k nim – údaje zo súboru i z konzoly môžeme čítať rovnakými programovými prostriedkami a to isté platí pre zápis.

Štandardná knižnica C++ obaľuje koncepciu prúdov do objektovej podoby a poskytuje nám hierarchiu tried, pomocou ktorých môžeme pristupovať k údajom. Na dokonalú možnosť kontroly práce s prúdmi poskytuje množstvo riadiacich funkcií a pre zjednodušenie pretypuje niektoré základné operátory.

Prúdové triedy a funkcie na prácu s nimi sú deklarované v hlavičkových súboroch fstream, iomanip, ios, iosfwd, iostream, istream, ostream, sstream, streambuf a strstream. Názvy jednotlivých hlavičkových súborov korešpondujú s triedami, ktoré sú v nich obsiahnuté.

Základom celej hierarchie je trieda ios_base. Táto trieda obsahuje predovšetkým údajové členy na formátovanie vstupu a výstupu údajov cez prúdy a na zaznamenanie informácií o vnútornom stave prúdu a niekoľko funkcií na prístup k týmto členom. Samostatne sa nepoužíva.

Od triedy ios_base je odvodená trieda ios. V skutočnosti je táto trieda inštanciou šablóny basic_ios, ktorá umožňuje určiť, či budú prúdy pracovať s jednobajtovými alebo multibajtovými znakmi. Pre jednoduchosť budeme v ďalšom texte hovoriť len o jednobajtových verziách tried. Všetky prúdové triedy, o ktorých si povieme, budú teda inštanciami príslušných šablón, ktorých mená dostaneme predradením reťazca basic_ pred názov triedy.

Trieda ios vytvára nadviazanie prúdu na vyrovnávaciu pamäť (inštanciu triedy streambuf) a poskytuje funkcie na riadenie tejto vyrovnávacej pamäte, ako aj na riadenie stavu prúdu. Ani táto trieda sa samostatne nepoužíva.

Trieda streambuf predstavuje všeobecný typ pre vyrovnávaciu pamäť prúdu. Nie je inštanciovateľná, pretože neobsahuje nijaký verejný konštruktor. Obsahuje mnoho členských funkcií na riadenie vyrovnávacej pamäte, za bežných okolností však s ňou ako programátori veľmi do styku neprídeme. Trieda streambuf je vrcholom inej hierarchie tried, nemá spojitosť (z hľadiska dedičnosti) s triedami odvodenými od ios.

Prvou použiteľnou triedou v hlavnej hierarchii je trieda istream, ktorá je priamym potomkom triedy ios. Ako jej názov evokuje, je určená na vstup údajov, ktoré číta z pridruženej vyrovnávacej pamäte. Ak však chceme triedu istream reálne použiť, musíme sa o pridelenie vhodnej vyrovnávacej pamäte postarať sami. Preto je táto trieda vhodná skôr v prípade, že potrebujeme čítať údaje z iných zdrojov, ako nám poskytuje štandardná knižnica (napríklad zo sieťových socketov). Trieda istream obsahuje niekoľko členských funkcií na čítanie jedného či viacerých znakov [get(), read()], na vrátenie naposledy prečítaného znaku späť do prúdu [putback()] a na zmenu aktuálnej pozície ukazovateľa vstupu [seekg() – má, samozrejme, zmysel len pri podobných zdrojoch údajov, ako sú súbory]. Navyše poskytuje pretypovaný operátor >> na formátované čítanie údajov. Príklad použitia uvedieme o chvíľu. Počas behu programu máme k dispozícii automaticky vytvorenú inštanciu triedy istream s názvom cin, ktorá je naviazaná na vstupnú konzolu, a teda je ekvivalentom neobjektového prúdu stdin.

Komplementárnou k triede istream je (prekvapujúco) trieda ostream, takisto odvodená od triedy ios. Aj táto trieda je združená s vyrovnávacou pamäťou a pre spôsoby jej využitia platí to, čo sme uviedli v predchádzajúcom odseku. Členské funkcie triedy ostream majú podobný význam – zápis jedného či viacerých znakov [put(), write()], zmena ukazovateľa výstupnej pozície [seekp()], spláchnutie (vyčistenie??) vyrovnávacej pamäte [flush()]. Okrem toho môžeme na formátovaný výstup údajov používať pretypovaný operátor <<. Pri štarte programu sa automaticky vytvoria tri inštancie triedy ostream s názvami cout, cerr a clog, napojené na výstupnú konzolu. Prvá z nich je ekvivalentom prúdu stdout, druhé dve nahrádzajú prúd stderr. Rozdiel medzi nimi je v tom, že cerr je bez vyrovnávacej pamäte a clog ju obsahuje.

Od tried istream a ostream je odvodená trieda iostream, ktorá slúži na implementáciu prúdov, nad ktorými potrebujeme súčasne vykonávať operácie čítania aj zápisu. Sama osebe nezavádza nijakú novú funkčnosť, je prostým zložením oboch svojich rodičovských tried.

Štandardná knižnica poskytuje dve špecializácie prúdových tried pre konkrétne údajové zdroje či spotrebiče. Prvou sú prúdy pracujúce s reťazcami. Vyrovnávaciu pamäť nadviazanú na reťazec v pamäti predstavuje trieda stringbuf. Táto trieda je potomkom triedy streambuf a reťazec, s ktorým je spojená, musí byť inštanciou triedy string (opíšeme neskôr). S funkciami triedy stringbuf podobne ako pri jej rodičovi do kontaktu veľmi neprichádzame.

Vstupný prúd na čítanie z reťazca je realizovaný triedou istringstream. Táto trieda je odvodená od triedy istream, ktorej funkčnosť bezo zvyšku preberá a navyše pridáva len možnosť globálneho prístupu k reťazcu, na ktorý je nadviazaná.

Výstup do reťazca má na starosti trieda ostringstream. Ako potomok triedy ostream umožňuje rovnaký spôsob zápisu údajov, pridaná funkčnosť je totožná s triedou istringstream.

Logickým spojením oboch predchádzajúcich tried je trieda na vstup aj výstup z/do reťazca s predpokladaným názvom stringstream. Pozor, táto trieda je odvodená od triedy iostream, ku ktorej pridáva rovnakú funkčnosť ako istringstream a ostringstream.

V niektorých implementáciách nájdeme aj prúdy, ktoré budú pracovať nad klasickými, nulou ukončenými reťazcami jazyka C. Triedy, ktoré ich realizujú, majú podobné názvy: strstreambuf, istrstream, ostrstream a strstream.

Druhou špecializáciou sú prúdy na prácu so súbormi. Ich základom je opäť vyrovnávacia pamäť, ktorú tentoraz predstavuje trieda filebuf. Táto trieda je potomkom triedy streambuf a z jej verejne prístupných členských funkcií sú zaujímavé funkcie open() a close() na otvorenie a zavretie príslušného súboru a funkcie na nastavenie aktuálnej pozície [seekpos(), seekoff()]. V praxi je trieda filebuf opäť viac-menej v pozadí.

Na čítanie zo súboru máme k dispozícii triedu ifstream. Jej predkom je podľa očakávania trieda istream,  a tak z hľadiska funkčnosti sú v triede ifstream nové len funkcie open() a close(), ktoré volajú svoje ekvivalenty z triedy filebuf. Súbor, nad ktorým trieda ifstream pracuje, sa zadáva buď ako argument konštruktora, alebo ako argument funkcie open().

Trieda ofstream naproti tomu má na starosti výstup do súboru. Asi netreba nijako zdôrazňovať, že je odvodená od triedy ostream a že obsahuje podobné funkcie open() a close() ako trieda ifstream. Meno súboru, do ktorého zapisujeme, sa zadáva rovnako ako v predchádzajúcom prípade.

Poslednou triedou, ktorá zapadne do celkovej mozaiky, je trieda fstream, slúžiaca, ako iste tušíte, na súčasné čítanie aj zápis z/do súboru. Táto trieda je odvodená od triedy iostream a takisto zavádza funkcie open() a close() na otvorenie, resp. zavretie súboru.

V hlavičkovom súbore iomanip nájdeme niekoľko tzv. manipulátorov, čo sú funkcie, ktoré určitým spôsobom upravujú formátovanie výstupu. Používajú sa v súvislosti s pretypovanými operátormi << a >>.

Ukážme si teraz niekoľko príkladov na použitie prúdov. Prvý úsek programu vytlačí na konzolu vhodne formátovanú tabuľku druhých mocnín prvých desiatich prirodzených čísel:

#include <iostream>
#include <iomanip>
using namespace std;
 
void main()
{
  for (int i = 1; i <= 10; i++)
    cout << setw(2) << i << setw(4) << i*i << endl;
}

V programe vidíme, akým spôsobom sa používa pretypovaný operátor << na zápis údajov do prúdu. Ľavým jeho operandom musí byť príslušný prúd, pravým premenná či konštanta, ktorú chceme do prúdu zapísať. Pozor, číselné hodnoty sa zapisujú ako reťazce, a nie ako binárne čísla! Vypísanie obsahu premennej i na konzolu zabezpečíme teda jednoduchým zápisom cout << i. Aký je to rozdiel oproti klasickému printf("%d", i), kde musíme navyše vo formátovacom reťazci explicitne vyjadriť typ premennej i! Čítanie údajov z prúdu sa realizuje podobne: cin >> i spôsobí, že sa z prúdu cin prečíta reťazec číslic tvoriaci celé číslo a uloží sa po konverzii do premennej i. Pravidlá rozoznávania číselných údajov sú rovnaké ako pri rodine funkcií scanf().

Pretypovaný operátor <<, resp. >> vracia ako návratovú hodnotu referenciu na prúd, s ktorým pracoval, preto je možné operátory reťaziť ako v našom príklade. Operátory sú deklarované ako nečlenské funkcie. Pre výstup vlastných údajových typov (obyčajne objektových) môžeme v programe oba operátory prekryť vlastnými funkciami, ale musíme dodržať prototyp, ktorý je v prípade operátora << takýto:

ostream& operator<<(ostream&, typ);
 
a v prípade operátora >> takýto:
 
istream& operator>>(istream&, typ&);

Prekryté funkcie dostávajú ako jeden z argumentov referenciu na príslušný prúd, s ktorým môžu pracovať podľa svojich potrieb. Na účel možného zreťazenia operátorov musia vlastné funkcie vracať referenciu na ten istý prúd, ktorý dostali ako argument.

V programe vidíme aj použitie manipulátorov prúdu: setw() nastavuje šírku výstupného poľa, zapisovaný údaj bude v tomto poli zarovnaný doprava. Manipulátory tohto typu [okrem setw() sú to ešte setprecision(), setfill(), setbase(), setiosflags()] sú vlastne náhradou možností formátovacieho reťazca funkcie printf(). Zvláštnym manipulátorom je funkcia endl, ktorá zapisuje do prúdu znak nového riadka. Na rozdiel od priameho zápisu znaku '\n' navyše spláchne (vyčistí??) výstupnú vyrovnávaciu pamäť prúdu. Spolu s podobnou funkciou ends, ktorá zapisuje nulový ukončovač reťazca, sú deklarované v hlavičkovom súbore ostream. K dispozícii máme aj niekoľko manipulátorov, ktoré sú skratkovými vyjadreniami uvedených parametrických manipulátorov, ako napríklad dec, hex, left, right, scientific a pod. Zoznam všetkých možných manipulátorov nájdete v dokumentácii k prekladaču.

Druhý príklad bude čítať údaje z jedného súboru (in.txt) a zapisovať ich do druhého súboru (out.txt):

#include <iostream>
#include <fstream>
using namespace std;
 
void main()
{
  ifstream in("in.txt");
  if (!in)
  {
    cerr << "Input file open error" << endl;
    return;
  }
 
  ofstream out("out.txt");
  if (!out)
  {
    cerr << "Output file open error" << endl;
    in.close();
    return;
  }
 
  while (true)
  {
    unsigned char c;
 
    in >> c;
    if (in.eof())
      break;
    if (!in)
    {
      cerr << "Read error" << endl;
      break;
    }
 
    out << c;
    if (!out)
    {
      cerr << "Write error" << endl;
      break;
    }
  }
 
  in.close();
  out.close();
}

Program je doplnený aj ošetrením prípadných chybových stavov. Vidíme, že prúdové triedy majú prekrytý operátor !, ktorý svojou nenulovou hodnotou indikuje chybu pri práci s prúdom. Koniec súboru detegujeme pomocou členskej funkcie eof(). Pre zaujímavosť si skúste program napísať pomocou klasických funkcií jazyka C – uvidíte, ktorý spôsob je čitateľnejší a jednoduchší.

Kontajnerové triedy

Druhou skupinou tried v štandardnej knižnici sú kontajnerové triedy. Kontajnerom sa v tomto prípade myslí zvláštny údajový typ, ktorý slúži na uchovávanie hodnôt rovnakého typu. Kontajnery sú v podstate tým, čo absolventi informatiky (ale nielen oni) poznajú z programovacích techník pod názvom abstraktný údajový typ (ADT). Všetky ďalej uvedené triedy sú šablónami, umožňujú tak pracovať s ľubovoľným typom. Tento typ ukladaných údajov je vždy parametrom šablóny.

Prvou kontajnerovou triedou je bitset. Táto trieda predstavuje bitovú mapu, čo je postupnosť bitov, ktoré môžeme po jednom nastavovať, nulovať, invertovať; prístup k nim je možný takisto pomocou pretypovaného indexovacieho operátora. Okrem neho je pretypované aj množstvo iných operátorov na zjednodušenie práce s bitovou mapou. Veľkosť mapy je parametrom šablóny.

Trieda deque je „obojstrannýmfrontom (z anglického double-ended queue). Obojstranný front umožňuje na rozdiel od bežného frontu (pozri ďalej) prístup k údajom na obidvoch koncoch a aj náhodný prístup k ľubovoľnému prvku frontu. Na pridávanie prvkov obsahuje funkcie insert(), push_front(), push_back(), na odoberanie erase(), pop_front() a pop_back(). Na priamy prístup máme k dispozícii pretypovaný operátor indexovania.

Ďalšou triedou je trieda list, ktorá implementuje obojsmerný zreťazený zoznam. Vkladanie a vyberanie prvkov sa realizuje podobnými funkciami ako v triede deque, ale nie je možný priamy indexovaný prístup. Zoznam možno, samozrejme, usporiadať a pomocou funkcie merge() aj vložiť do iného zoznamu pri zachovaní usporiadania.

Triedy map a multimap realizujú typ, obyčajne nazývaný asociatívne pole, hash tabuľka alebo slovník. Prístup k jednotlivým prvkom takéhoto poľa sa deje prostredníctvom kľúčov, ku ktorým sú asociované uložené hodnoty. Je zrejmé, že pri ukladaní prvkov do poľa musíme uviesť vždy dvojicu kľúč – hodnota. Typ kľúča je jedným z parametrov šablóny. Trieda multimap na rozdiel od triedy map povoľuje pre jeden kľúč viacero asociovaných hodnôt a neumožňuje prístup a vkladanie hodnôt pomocou indexovacieho operátora. Hodnoty môžeme vkladať aj funkciou insert(), mazanie má na starosti funkcia erase().

Variáciou na tému front je trieda priority_queue, ktorá predstavuje prioritný front, čo je front, ktorého prvky sú zoradené podľa priority a vkladanie toto zoradenie zachováva. Inak sa nelíši od nasledujúcej triedy.

Trieda queue je implementáciou klasickej FIFO štruktúry, nazývanej front. Do frontu sa údaje pridávajú na jednej strane a odoberajú na druhej strane. Iný prístup k prvkom frontu nie je možný. Pridávanie má na starosti funkcia push(), odoberanie funkcia pop().

Triedy set a multiset sú príbuzné triedam map a multimap, na rozdiel od nich však obsahujú iba kľúče. Trieda set zaručene obsahuje rôzne kľúče, zatiaľ čo pre triedu multiset toto obmedzenie neplatí. Obe triedy v podstate realizujú všeobecný koncept množiny.

Zásobník je implementovaný pomocou triedy stack. Ide o klasickú štruktúru typu LIFO, z ktorej môžeme vyberať prvky len presne v opačnom poradí, ako boli do nej vložené. Podobne ako pri triede queue vkladanie a vyberanie majú na starosti triedy push() a pop().

Poslednou kontajnerovou triedou je trieda vector. Tá predstavuje jeden z najpoužívanejších typov, ktorý si môžeme predstaviť ako dynamické pole, ktorého veľkosť sa prispôsobuje aktuálnemu počtu prvkov. Je podobná triedam deque a list, každá z týchto troch tried je však optimalizovaná pre iný spôsob prístupu k prvkom. Bližšie detaily presahujú rámec nášho rozprávania a nájdete ich v dokumentácii.

S kontajnerovými triedami sú neoddeliteľne späté tzv. iterátory. Ide o niekoľko tried, ktoré predstavujú objektové typy podobné ukazovateľom, pomocou ktorých môžeme k jednotlivým prvkom kontajnera pristupovať podobným spôsobom, ako môžeme pomocou bežných ukazovateľov pristupovať k prvkom bežných, neobjektových polí. Menovite ich môžeme dereferencovať, inkrementovať a niektoré i dekrementovať, porovnávať medzi sebou a pod. V hlavičkovom súbore algorithm nájdeme niekoľko funkcií, ktoré realizujú množstvo často používaných operácií nad kontajnermi a na svoju činnosť využívajú práve iterátory.

Iterátormi sa tu bližšie zaoberať nebudeme. Ide o priveľmi sofistikovanú tému na to, aby sa dala objasniť na takom malom priestore, takže ak sa nenahneváte, odkážem vás opäť na elektronickú dokumentáciu, kde nájdete presný opis jednotlivých druhov iterátorov a príklady ich použitia.

Ďalšie triedy

ANSI C++ poskytuje sústavu tried na podporu národných prostredí, pomocou ktorých môže program používať správne formátovanie čísel, dátumu, času a meny. Základom tejto sústavy je trieda locale, ktorá definuje všetky potrebné charakteristiky prostredia a umožňuje jeho dynamickú zmenu. Okrem tejto triedy nájdeme v hlavičkovom súbore s rovnakým názvom locale niekoľko ďalších pomocných tried na opis konverzie znakov, opis formátovacích pravidiel a pod.

V štandardnej knižnici C++ máme k dispozícii niekoľko nových tried s uplatnením v matematike. Pravdepodobne najdôležitejšia je trieda complex, ktorá reprezentuje komplexné čísla, definuje pre ne množstvo operácií a pretypuje najbežnejšie operátory. S inštanciami triedy complex pracujú nové verzie matematických funkcií ako sin(), exp() a pod. (áno, funkcia sínus je definovaná aj na komplexnom obore).

Ostatné matematické triedy sú menej dôležité – trieda valarray slúži na reprezentáciu usporiadaných množín, s ňou spolupracujú triedy slice a gslice na výber z množiny. Trieda numeric_limits opisuje implementačne závislé vlastnosti číselných údajových typov.

Pre prácu s reťazcami bola zavedená trieda string (v skutočnosti inštancia šablóny basic_string pre typ char; možné sú, samozrejme, aj viacbajtové reťazce). Členské funkcie triedy string pokrývajú širokú škálu operácií nad reťazcami – od rozširovania, skracovania reťazca cez úpravy častí reťazca až po prehľadávanie a porovnávanie rôznych reťazcov.

Výnimky majú v štandardnej knižnici vlastnú hierarchiu tried. Na jej vrchole je trieda exception, od ktorej sú odvodené dve triedy logic_error a runtime_error pre dva rôzne okruhy výnimiek. Od týchto tried sú potom odvodené konkrétne výnimkové triedy špecifické pre tú-ktorú časť štandardnej knižnice. Za zmienku stoja ešte výnimky vyhadzované priamo konštrukciami jazyka, ako bad_alloc (pri chybe alokácie operátorom new), bad_exception (pri výskyte neočakávanej výnimky), bad_cast (pri nedovolenom pretypovaní pomocou operátora dynamic_cast) a bad_typeid (pri nesprávnom použití operátora typeid). Všetky výnimkové triedy sú deklarované v hlavičkovom súbore stdexcept.

Štandardná knižnica C++ obsahuje okrem všetkých týchto tried množstvo ďalších, na ktoré sa tu dnes nedostalo. Bohužiaľ, nie je možné opísať tu celú knižnicu podrobne, zabralo by to podstatne viac miesta, ako poskytuje jedno celé číslo PC REVUE. Vy však viete, že najlepším učiteľom je vlastná prax a najviac sa vždy dozviete samostatným hľadaním v dostupných manuáloch, referenčných príručkách a v neposlednom rade aj opakovaným skúšaním vo vlastných programoch. Tento prístup k učeniu som razil počas celého seriálu a verím, že sa ním riadite a budete riadiť aj naďalej.

Čo dodať na záver?

Rozprávaním o štandardnej knižnici sme teda vyčerpali celú problematiku C++. Bez zbytočnej samochvály si myslím, že dosiaľ neexistuje v slovenčine materiál, ktorý by sa venoval ANSI C++ v takomto rozsahu. Pevne verím, že tým, ktorí C++ neovládali, seriál pomohol tento veľmi krásny jazyk zvládnuť, tým, ktorí už s C++ prišli do styku, zase pomohol osviežiť pamäť a zopakovať zabudnuté vedomosti. Skôr než skončím, dovoľte mi poďakovať sa vám za priazeň i za ohlasy, ktoré ma presvedčili, že to, čo robím, má zmysel. Aby som bol korektný voči tým, ktorí pomohli zase mne, uvádzam tu ešte zoznam literatúry, z ktorej som čerpal. Základným a neoceniteľným zdrojom informácií bola kniha C++ Reference Manual od Bjarne Stroustrupa. V novších veciach mi nesmierne pomohla kniha Jazyky C a C++ podle normy ANSI/ISO z vydavateľstva Grada. Jeden z jej autorov, Miroslav Virius, má „na svedomí“ mnoho článkov v časopisoch Chip či Softwarové noviny, ktoré mi často pomohli objasniť to, čomu som dosiaľ nie celkom rozumel. No a, samozrejme, nemôžem vynechať dokumentáciu k prekladačom, predovšetkým k výbornému Visual C++ 6.0, ktorého som, podotýkam, legálnym vlastníkom (ak by to niekoho zaujímalo ;–).

Nuž, čo viac dodať? Seriál pre mňa znamenal úplne novú skúsenosť a tak trochu mi je ľúto, že už končíme. Ale život ide ďalej a ja verím, že sa čoskoro opäť stretneme na stránkach PC REVUE pri ďalších článkoch z môjho pera. Prajem vám veľa úspechov v používaní vašich nadobudnutých vedomostí a dúfam, že budete šíriť „céplusplusovskú“ osvetu ďalej.

C++

Nechajte si posielať prehľad najdôležitejších správ emailom

Mohlo by Vás zaujímať

Ako na to

Ako zbaviť fotky hmly

08.12.2016 11:59

Hmla alebo dym sú často veľmi kreatívne nástroje. No všetkého veľa škodí. Fotka potom stráca kontrast a v podstate na nej nič nevidieť. Hmlu môžete neraz následnými úpravami odstrániť alebo zredukovať ...

Ako na to

Užitočné SW nástroje

08.12.2016 11:53

AllDup v4.0.3 Určenie: program na vyhľadávanie a odstraňovanie duplicitných súborov Vlastnosti: duplicitné súbory sa vyhľadávajú len na zvolených diskových jednotkách alebo len v rámci vybraných ...

Ako na to

Fotografovanie s bleskom

08.12.2016 11:47

Ak máte moderný fotoaparát so vstavaným alebo externým bleskom, zdá sa vám téma článku triviálna. Jednoducho nastavíte vhodný režim, vyberiete najlepšiu kompozíciu záberu, exponujete a o zvyšok sa už ...

Žiadne komentáre

Vyhľadávanie

Kyocera - prve-zariadenia-formatu-a4-s-vykonom-a3

Najnovšie videá