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++
Funkční objekty v C++
4. prosince 2001, 00.00 | Funkční objekt je instance třídy, která má jako svou veřejnou metodu operátor (), tedy operátor pro volání funkce. V dnešním článku si ukážeme jak zobecnit funkci, a jak používat funkční objekt na místě, kde se očekává ukazatel na funkci.
Funkční objekt je instance třídy, která má jako svou veřejnou metodu operátor (), tedy operátor pro volání funkce. V dnešním článku si ukážeme jak zobecnit funkci, jak používat funkční objekt na místě, kde se očekává ukazatel na funkci. Než se začneme věnovat využití funkčních objektů, zopakujeme si, jak přetížit operátor (). Ukážeme si vytvoření jednoduchého funkčního objektu.
|
Vytvořili jsme si jednoduchou třídu funkčních objektů, třída ma operátor () pro parametr int. Instanci této třídy tedy lze použít (zapsat) jako funkci (volání funkce) s parametrem int. Jedná se pouze o ukázkový příklad, který nemá snad žádné využití. Než se dostaneme k poněkud užitečnějším funkčním objektům, podívejme se nejprve na jeden problém, který nemá s funkčními objekty nic společného.
Představme si, že chceme vytvořit funkci, která zjistí, kolik prvků v nějakém kontejneru, nebo poli vyhovuje nějaké podmínce. Podmínku v době psaní naší funkce neznáme. Naše funkce by měla být univerzálně použitelná, pro jakoukoliv podmínku. Jedno z možných řešení je mít jako parametr naší funkce ukazatel na funkci vracející bool, která vrátí, zda její parametr odpovídá podmínce. Ukažme si to na příkladu.
|
Naše funkce početPlatných může mít jako svůj třetí parametr jakoukoliv funkci (ukazatel na funkci), která má jako parametr int a vrací bool. Toto řešení má několik nedostatků. Za prvé v momentě, kdy budeme chtít, použít jinou podmínku (Například <5 místo <3.), nebudeme moci použít funkci podmínka, budeme muset napsat novou podmínku. To by se snad dalo ještě obejít pomocí globální proměnné, ale problém by nastal, kdyby jsme chtěli například podmínku 3 < x < 5. Naše funkce početPlatných by se už vůbec nedala použít pro pole, nebo kontejner obsahující jiné prvky než int. Chceme-li napsat opravdu obecnou funkci početPlatných, musíme použít funkční objekty.
Kdyby jsme si chtěli vytvořit nějakou třídu s definovaným operátorem (), a její instanci použít jako parametr naší funkce početPlatných, překladač by to odmítl jako nekompatibilitu typů. (Instance třídy není ukazatel na funkci.) Musíme naší šablonu funkce početPlatných poněkud zobecnit. Parametrem šablony nebude jenom typ iterátoru, ale další typ, který jsem nazval Funkce. Třetí parametr funkce početPlatných bude parametr typu Funkce. Tím docílíme toho, že parametrem může být "cokoliv". Tělo funkce početPlatných nijak měnit nemusíme. Podíváme-li se podrobně na vzniklou šablonu funkce zjistíme, že za typ Funkce může být dosazen buď typ funkce s jedním parametrem, která vrací bool (V našem případě může vracet i int.), nebo třída, která má jako veřejnou metodu operátor () s jedním parametrem, vracejícím bool, nebo int. Podívejme se na příklad.
|
Šablona funkce početPlatných je nyní hodně obecná. Lze ji použít na jakýkoliv kontejner, obsahující instance jakéhokoliv typu. Podmínka může být libovolná, kterou lze v C++ zapsat. Použití šablony funkce početPlatných je znázorněno v jednoduché funkci main. Vytvořili jsme vlastně něco jako obecný algoritmus pracující s kontejnery. V knihovně STL je implementováno mnoho algoritmů pracujících s kontejnery. Až se budeme algoritmy v STL zabývat (což by mělo být v článku po následujícím článku), uvidíme, že v STL je i obdoba naší šablony funkce početPlatných.
Dnes jsme si předvedli princip funkčních objektů. Ještě než se podíváme na standardní algoritmy v STL, budeme se v příštím článku zabývat funkčními objekty v STL. V STL je také několik standardních funkčních objektů. Funkční objekty se velmi často používají pro práci se standardními algoritmy, ale je možné je používat i u vlastních šablon funkcí, či metod.
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