Hlavnφ
Hlavnφ strana
Seznam Φlßnk∙
NejΦten∞jÜφ Φlßnky
Progres e-mailem
Visual C++ FAQ

Serißly
COM
ISAPI

banner1.gif (2545 bytes)

Nenechte si ujφt
NeobdΘlnφkovß okna
Tisk bez Preview
MFC a DLL
Logo v MDI ploÜe
Kouzla s kombo-boxem
V²jimky v C++

banner.gif (3305 bytes)

èablony v C++ dφl 1. Jan Odvßrko
02.11.1999
[Hlavnφ strßnka]  |  [Rubrika]

1.1 Co je to Üablona - template?
Mechanismus Üablon v C++ n∞kdy takΘ naz²van² jako genericita, dovoluje programßtor∙m vytvß°et parametrizovanΘ moduly, jejich₧ parametrem m∙₧e b²t i n∞jak² blφ₧e neurΦen² (primitivnφ, nebo objektov²) typ. Co p°esn∞ tato komplikovanß definice znamenß si ukß₧eme na jednoduchΘm p°φkladu. P°edstavme si, ₧e vytvß°φme kolekci objekt∙ a sna₧φme se urΦit typ prvk∙, kterΘ tato kolekce bude obsahovat. Mßme samoz°ejm∞ n∞kolik mo₧nostφ.

  • Typ prvk∙ m∙₧e b²t napevno urΦen². Pokud pou₧ijeme kup°φkladu typ int, z°φkßme se tak mo₧nosti vklßdat do seznamu jinΘ hodnoty ne₧ celoΦφselnΘ. Pokud budeme chtφt v budoucnu vytvo°it nap°φklad kolekci Φφsel s pohyblivou desetinnou Φßrkou musφme vytvo°it dalÜφ kolekci. Smφ°it se asi budeme muset s tφm, ₧e zdrojov² k≤d obou kolekcφ bude velmi podobn² (mo₧nß skoro ·pln∞ stejn²) a liÜit se bude pouze pou₧it²m typem.

  • Jako typ m∙₧eme pou₧φt obecn² ukazatel void. V tomto p°φpad∞ lze sice do kolekce vklßdat r∙znΘ typy objekt∙, ale p°i p°φstupu k t∞mto objekt∙m musφme v₧dy provßd∞t p°etypovßnφ, co₧ nikdy nenφ bezpeΦnß akce.

  • DalÜφ mo₧nostφ je vytvo°enφ abstraktnφho typu (abstraktnφ t°φdy) a odkazovat se pomocφ n∞j na prvky v kolekci. V tomto okam₧iku m∙₧eme vklßdat do kolekce instance t∞ch t°φd, kterΘ d∞dφ (p°φmo, nebo nep°φmo) z tΘto abstraktnφ t°φdy (vyu₧φvßme zde polymorphism). Pro instance t°φd z jin²ch hierarchiφ vÜak musφme vytvß°et dalÜφ kolekce.

Ideßlnφm °eÜenφm by bylo vytvo°enφ takovΘ t°φdy, kterß by typ prvk∙ urΦovala ve svΘm parametru. Vytvo°it jak²si parametrizovan² vzor, podle kterΘho by se vytvß°ely skuteΦnΘ t°φdy. A prßv∞ v tuto chvφli se dostßvajφ ke slovu Üablony - templates.

V jazyce C++ existujφ dva typy Üablon, Üablony funkcφ (function templates) a Üablony t°φd (class templates). M∙₧eme vÜak °φci, ₧e ty pravΘ v²hody pou₧itφ Üablon jsou patrnΘ p°edevÜφm p°i pou₧itφ Üablon t°φd.

1.2 V²hody Üablon
Jednou z velk²ch v²hod je skuteΦnost, ₧e pouh²m vytvo°enßm Üablony jeÜt∞ nevznikß binßrnφ k≤d. Odpovφdajφcφ binßrnφ k≤d je kompilßtorem vytvo°en² a₧ v okam₧iku dosazenφ parametr∙ a vytvo°enφ instance Üabony (tedy t°φdy, nebo funkce) a jejφ nßslednΘ pou₧itφ. Tento princip zajiÜ¥uje, ₧e ve v²slednΘm p°elo₧enΘm souboru je obsa₧en pouze ten k≤d, kter² skuteΦn∞ pou₧φvßme (to m∙₧e b²t p°i pou₧itφ velk²ch knihoven Üablon ohromnß ·spora). Vzhledem k tomu, ₧e jsou Üablony distribuovßny s kompletnφm zdrojov²m k≤dem, m∙₧e dobr² kompilßtor dßle optimalizovat k≤d i tφm, ₧e vynechß veÜker² nepou₧it² k≤d (v₧dy se najde n∞jakß metoda t°φdy, kterou nepou₧ijeme).

P°φkladem knihoven Üablon m∙₧e b²t ATL - Active Template Library, kterß je urΦena pro v²voj COM objekt∙, nebo STL - Standard template library, je₧ je distribuovßna s knihovnou MFC.

1.3 èablony funkcφ
Pomocφ Üablon funkcφ m∙₧eme definovat mno₧inu funkcφ se stejn²m k≤dem, kterΘ pou₧φvajφ r∙znΘ datovΘ typy. Prvnφm p°φkladem bude jednoduchß Üablona funkce pro zjiÜt∞nφ maxima ze dvou prom∞nn²ch blφ₧e neurΦenΘho typu.

template <typename TYPE> TYPE Max(TYPE a, TYPE b)
  { return (a 
> b) ? a : b; }

èablona oΦekßvß jedin² parametr TYPE, kter² urΦuje typ dvou porovnßvan²ch parametr∙ funkce a typ nßvratovΘ hodnoty funkce. èablona p°edpoklßdß, ₧e pro dosazen² typ bude definovßn operßtor ">". PozornΘho Φtenß°e jist∞ napadne, ₧e typ m∙₧e b²t jak primitivnφ, tak u₧ivatelem definovan² objektov².

Ve starÜφch verzφch se mφsto klφΦovΘho slova typename pou₧φvalo klφΦovΘ slovo class. Domnφvßm se vÜak, ₧e tato zm∞na byla provedena sprßvn∞, proto₧e klφΦovΘ slovo class bylo zavßd∞jφcφ.

Pou₧itφ Üablony funkce (tj. vytvo°enφ instance -  funkce) je jednoduchΘ a spoΦφvß v jejφm zavolßnφ. Podφvejme se na krßtkou ukßzku.

  int a=10, b=20;
  int c = Max(a, b);

  double d1=10.1, d2= 20.2;
  double d3 = Max(d1, d2);

  printf("Maxima: %d, %f\n", c, d3);

V p°edchozφm p°φkladu je vid∞t pou₧itφ Üablony pro r∙znΘ datovΘ typy. V tuto chvφli je takΘ kompilßtorem vygenerovan² odpovφdajφcφ k≤d dvou funkcφ, pro typ int a pro typ double. Pokud explicitn∞ neuvedeme p°i volßnφ funkce datov² typ (nßÜ p°φpad), neprovßdφ kompilßtor ₧ßdnΘ p°etypovßnφ a typ parametr∙ musφ b²t samoz°ejm∞ stejn². Nßsledujφcφ ukßzka zobrazuje chybnΘ pou₧itφ Üablony.

  double d = Max(11.1);

Tento p°φpad vÜak m∙₧eme opravit explicitnφm urΦenφm parametru, kter² zajistφ automatickou typovou konverzi.

  double d = Max<double>(11.1);

Bez pou₧itφ mechanismu Üablon funkcφ bychom museli definovat dv∞ typov∞-bezpeΦnΘ funkce, viz. nßsledujφcφ ukßzka.

int Max(int a, int b) { return (a < b) ? a : b; }
double Max(double a, double b) { return (a < b) ? a : b; }

1.4 èablona vs. makro
P°edchozφ p°φklad lze vy°eÜit takΘ pomocφ maker. M∞jme vÜak na pam∞ti zßsadnφ rozdφl mezi makrem a Üablonou. Makra jsou °eÜena textov²m preprocesorem jazyka, tj. jednß se pouze o jednoduchΘ dosazovßnφ textu, kde₧to Üablony jsou vyhodnocovßny kompilßtorem.

Pro zjiÜt∞nφ maxima za dvou prom∞nn²ch bychom mohli pou₧φt nßsledujφcφ makro.

#define MAX(a, b) (((a) > (b)) ? (a) : (b))

Je zde vÜak n∞kolik zßsadnφch rozdφl∙:

  • Nelze ₧ßdn²m zp∙sobem kontrolovat typy dosazen²ch parametr∙.

  • Parametry 'a' a 'b' jsou vyhodnoceny dvakrßt. Pokud bychom dosadili nap°φklad prom∞nnou s inkrementaΦnφm operßtorem ++, bude jejφ hodnota zv²Üena dvakrßt.

  • Proto₧e jsou makra vyhodnocena preprocesorem bude p°i p°φpadnΘ chyb∞ kompilßtor odkazovat na mφsto pou₧itφ, mφsto na definici makra.

1.5 DalÜφ p°φklad Üablony funkce
DalÜφm p°φkladem pou₧itφ Üablony funkce m∙₧e b²t kup°φkladu funkce, kterß vym∞nφ hodnoty dvou parametr∙. Podφvejme se na nßsledujφcφ p°φklad.

template <class TYPE> void Swap( TYPE& a, TYPE& b )
{
  TYPE c(a);
  a = b;
  b = c;
}

Pou₧itφ Üablony, kterß °eÜφ v²m∞nu hodnot je ideßlnφ, proto₧e kompilßtor kontroluje typy parametr∙ a zajiÜ¥uje tak jejich shodnost ji₧ v okam₧iku kompilace (v naÜem p°φpad∞ je typovß kontrola velice d∙le₧itß).

Pou₧itφ tΘto Üablony je op∞t znßzorn∞no na nßsledujφcφ ukßzce.

  double d = 10.0;
  int a=10, b=20;

  Swap(a, b);    // OK
  Swap(a, d);    // Error - r∙znΘ typy

  printf("a=%d, b=%d\n", a, b);

Jak ji₧ bylo °eΦeno parametrem Üablony m∙₧e b²t i objektov², u₧ivatelem definovan², typ. ProhlΘdn∞me si op∞t nßsledujφcφ ukßzku zdrojovΘho k≤du.

  CMyObject o1, o2;
  Swap(o1, o2);

P°φÜt∞ Üablony t°φd...


PodobnΘ Φlßnky:

 
╚lßnek je za°azen do serißlu Nßsledujφcφ>>
èablony v C++ dφl 2.

Kdo Otßzka nebo p°ipomφnka

Prohlφ₧enφ p°φsp∞vk∙ nebo nov² p°φsp∞vek

O firm∞... Kontakt Ostatnφ