Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!
Zadejte Vaši e-mailovou adresu:
Kamarád fotí rád?
Přihlas ho k odběru fotomagazínu!
Zadejte e-mailovou adresu kamaráda:
C/C++
Standardní funkční objekty v C++
10. prosince 2001, 00.00 | V minulém článku jsme se seznámili s pojmem funkční objekt. Dnes si ukážeme jaké funkční objekty (třídy funkčních objektů) obsahuje standardní knihovna STL. Podíváme se na unární a binární funkční objekty, a také na šablony binder1st a binder2nd.
V minulém článku "Funkční objekty v C++" jsme se seznámili s pojmem funkční objekt. Dnes si ukážeme jaké funkční objekty (třídy funkčních objektů) obsahuje standardní knihovna STL. Jestliže chceme pracovat se standardními algoritmy, je dobré znát standardní funkční objekty, nebo si umět vytvořit vlastní. Standardním algoritmům v STL se budeme věnovat v příštím článku.
Šablony unary_function a binary_functionV STL existují třídy unárních a binárních funkčních objektů. Unární funkční objekt je funkční objekt, který má jen jeden parametr operátoru (). Binární funkční objekt je funkční objekt, který má dva parametry operátoru (). Šablony unary_function a binary_function jsou šablony struktur. Obě šablony slouží jako nadtřídy (Jedná se sice o struktury, ale budu používat raději pojem třída. Slovo "nadstruktura" se mi zdá nějaké divné.) pro třídy funkčních objektů. Nemají žádnou metodu, ani atribut. Obsahují pouze definici vnitřních typů. Neobsahují dokonce ani operátor (), proto se vlastně nejedná ani o třídy funkčních objektů. Každá standardní třída funkčních objektů je šablonou třídy (struktury), a dědí z jedné z těchto dvou šablon tříd (struktur). Každá standardní třída funkčních objektů rozšíří tyto šablony minimálně o operátor (). Šablona unary_function má dva parametry, první udává typ parametru, druhý udává typ návratové hodnoty operátoru(). Šablona binary_function má 3 parametry. První dva udávají typy prvního a druhého parametru operátoru(). Poslední parametr udává typ návratové hodnoty parametru (). Programátor, který používá funkční objekty s šablonami binary_function a unary_function nepříjde nijak do styku. Bude pracovat s šablonami odvozenými. Přesto si myslím, že je dobré o binary_function a unary_function vědět. Rovněž je dobré použít je jako nadtřídu při psaní vlastních tříd funkčních objektů. (Což jsem ve svém minulém článku neudělal, protože jsme takové šablony ještě neznali.)
Třídy unárních funkčních objektůŠablony tříd unárních funkčních objektů z STL jsou potomky šablony třídy (struktury) unary_function. Seznam některých tříd unárních funkčních objektů:
Název šablony | Činnost |
negate | Šablona má jeden parametr. Udává typ návratové hodnoty, i typ parametru operátoru (). Funkční objekt neguje svůj parametr. Je-li parametrem operátoru () proměnná (objekt) x, výsledek bude -x. |
logical_not | Šablona má jeden parametr. Udává typ parametru operátoru (). Návratová hodnota operátoru () je vždy typu bool. Funkční objekt neguje svůj parametr. Je-li parametrem operátoru () proměnná (objekt) x, výsledek bude !x. |
Třídy binárních funkčních objektů
Šablony tříd binárních funkčních objektů z STL jsou potomky šablony třídy (struktury) binary_function. Seznam některých tříd binárních funkčních objektů:
Název šablony | Činnost |
divides | Šablona má 1 parametr. Parametr udává typ obou parametrů a návratové hodnoty operátoru (). Operátor () vydělí své dva parametry. |
equalto | Šablona má 1 parametr. Parametr udává typ obou parametrů operátoru (). Operátor () vrací proměnnou typu bool. Vrací true v případě, že první parametr == druhý parametr. |
greater | Šablona má 1 parametr. Parametr udává typ obou parametrů operátoru (). Operátor () vrací proměnnou typu bool. Vrací true v případě, že první parametr > druhý parametr. |
greater_equal | Šablona má 1 parametr. Parametr udává typ obou parametrů operátoru (). Operátor () vrací proměnnou typu bool. Vrací true v případě, že první parametr >= druhý parametr. |
less | Šablona má 1 parametr. Parametr udává typ obou parametrů operátoru (). Operátor () vrací proměnnou typu bool. Vrací true v případě, že první parametr < druhý parametr. |
less_equal | Šablona má 1 parametr. Parametr udává typ obou parametrů operátoru (). Operátor () vrací proměnnou typu bool. Vrací true v případě, že první parametr <= druhý parametr. |
logical_and | Šablona má 1 parametr. Parametr udává typ obou parametrů operátoru (). Operátor () vrací proměnnou typu bool. Operátor () vrací první parametr && druhý parametr. |
logical_or | Šablona má 1 parametr. Parametr udává typ obou parametrů operátoru (). Operátor () vrací proměnnou typu bool. Operátor () vrací první parametr || druhý parametr. |
minus | Šablona má 1 parametr. Parametr udává typ obou parametrů a návratové hodnoty operátoru (). Operátor () vrátí rozdíl svých dvou parametrů. |
modulus | Šablona má 1 parametr. Parametr udává typ obou parametrů a návratové hodnoty operátoru (). Operátor () vrátí zbytek po celočíselném dělení. |
not_equal | Šablona má 1 parametr. Parametr udává typ obou parametrů operátoru (). Operátor () vrací proměnnou typu bool. Vrací true v případě, že první parametr != druhý parametr. |
plus | Šablona má 1 parametr. Parametr udává typ obou parametrů a návratové hodnoty operátoru (). Operátor () sečte své dva parametry. |
times | Šablona má 1 parametr. Parametr udává typ obou parametrů a návratové hodnoty operátoru (). Operátor () vynásobí své dva parametry. |
Všechny tyto třídy jsou deklarovány v hlavičkovém souboru function v prostoru jmen std. Omezení na parametr šablony vyplývá z její činnosti. Například šablona plus může mít jako svůj parametr typ, který má definován operátor + (implicitně, nebo definován operator+).
Nyní si ukážeme jednoduchý příklad. Ve svých článcích Množina a multimnožina v C++ a Asociativní pole v C++ jsem uvedl, že tyto kontejnery mají poslední, nepovinný parametr, kterým je funkční objekt. Implicitní hodnota posledního parametru je less<T>, kde T je první parametr kontejneru.
|
Tento příklad zatím asi nikoho nepřesvědčil o důležitosti funkčních objektů. Jejich význam se ukáže až v mých dalších článcích.
Šablony binder1st a binder2ndV souvislosti se standardními třídami funkčních objektů je dobré se také seznámit s šablonami binder1st a binder2nd. Jedná se o šablony tříd s operátorem (), který má 1 parametr. Obě třídy zapouzdřují binární funkční objekt (operátor () má 2 parametry) a jednu hodnotu. Tato hodnota bude daná jako první parametr u šablony binder1st nebo jako druhý parametr u šablony binder2nd. Zbývající parametr bude předán operátoru () jako parametr. Obě třídy tedy vlastně slouží k převedení binárního funkčního objektu na unární s pevně danou hodnotou jednoho ze svých parametrů. Zní to možná složitě, ale vše si ukážeme na jednoduchém příkladu. K vytvoření instancí tříd binder1st a binder2nd můžeme použít jednak konstruktory, nebo pomocné funkce jménem bind1st a bind2nd.
Ve svém minulém článku jsem ve svém posledním příkladu vytvořil šablonu funkce pocetPlatnych, která vrací počet prvků v kontejneru vyhovujících nějaké podmínce, která je také předána jako parametr. Podmínka je buď ukazatel na funkci s jedním parametrem, nebo funkční objekt, jehož operátor () má jeden parametr. Vytvořil jsem třídu funkčních objektů, která má jeden atribut. Takto jsem se snažil řešit problém, kdy operátor () má jen jeden parametr, já bych potřeboval aby měl dva. Nyní se podíváme jak napsat stejný příklad jen pomocí standardních šablon z STL. V STL existuje algoritmus count_if (Algoritmy podrobně probereme příště.), který dělá stejnou činnost jako moje funkce pocetPlatnych. S tím rozdílem, že vrací void, protože výsledek je uložen v posledním parametru, který je předáván jako reference. Zatímco moje funkce umožňovala vrátit výsledek pouze jako int, funkce count_if z STL má jako parametr i typ výsledku, což umožňuje ještě větší abstrakce. Můj poslední příklad z minulého článku napsaný jen pomocí standardních šablon vypadá takto:
|
Ve svých příkladech používám vždy kontejnery s primitivními datovými typy, nebo s řetězci. Musím ale zdůraznit, že vše lze použít i na kontejnery obsahující instance libovolných tříd, které mají definovány příslušné operátory.
Příště se podíváme na standardní algoritmy v STL.
Obsah seriálu (více o seriálu):
- Základy OOP v C++: Od C k C++
- Základní pojmy objektově orientovaného programování
- Vytváření tříd, instance třídy, zasílání zpráv v C++
- Vytváření instancí - konstruktory, destruktory
- Kopírovací konstruktor v C++
- Jednoduchá dědičnost v C++
- Časná versus pozdní vazba - úvod do polymorfismu v C++
- Polymorfismus - dokončení
- Vícenásobná dědičnost v C++
- Vícenásobná dědičnost v C++ - opakovaná dědičnost
- Vícenásobná dědičnost v C++ - volání konstruktorů a destruktorů
- Přetěžování operátorů v C++ 1.díl
- Přetěžování operátorů v C++ 2. díl
- Vstupní a výstupní operace pomocí datových proudů v C++
- Přetěžování operátorů << a >> pro datové proudy v C++
- Neformátovaný vstup a výstup v C++
- Paměťové proudy v C++
- Prostory jmen v C++
- Řetězce v C++
- Výjimky v C++
- Výjimky v C++ - výjimky tvoří dědičnou hierarchii
- Výjimky v C++ - dokončení
- Dynamická identifikace typů v C++
- Přetypování v C++
- Problémy s typy při vícenásobné dědičnosti
- Šablony funkcí v C++
- Šablony datových typů v C++
- Vnitřní typy u parametrů šablon, vnořené šablony v C++
- Pole s libovolným intervalem indexování v C++
- Datové kontejnery v C++ - Úvod do STL
- Vector - datový kontejner v C++
- Iterátory v C++
- Šablona vector v C++ a iterátory
- Asociativní pole v C++
- Množina v C++
- Funkční objekty v C++
- Standardní funkční objekty v C++
- Úvod do standardních algoritmů v C++
- Kopírovací a přesouvací algoritmy v C++
- Vyhledávací algoritmy v C++
- Skenovací (prohlížecí) algoritmy v C++
- Transformační algoritmy v C++
- Řadící algoritmy v C++
- Halda v C++
- Standardní algoritmy v C++ - dokončení
- Automatické ukazatele v C++
- Inteligentní ukazatel - čítač referencí v C++
- Použití čítače referencí v C++
- Kopírování velkých objektů v C++
- Řízené kopírování prvků v poli v C++
- Dokončení seriálu objektově orientované programování v C++
-
25. listopadu 2012
-
30. srpna 2002
-
10. října 2002
-
4. listopadu 2002
-
12. září 2002
-
25. listopadu 2012
-
28. července 1998
-
31. července 1998
-
28. srpna 1998
-
6. prosince 2000
-
27. prosince 2007
-
4. května 2007