Jazyk C++ II Dynamické identifikace typů
AR 2013/2014
Jazyk C++ II
Úvod Jak můžeme zjistit druh objektu, na který ukazuje ukazatel? V případě nemusíme typ objektu znát, pokud se jedná o funkci virtuální, kterou vlastní všechny třídy v hierarchii. Co když odvozený objekt obsahuje nezděděnou metodu? Jak registrovat typy vytvářených objektů? AR 2013/2014
Jazyk C++ II
2
RTTI
Run-time type information. Informace o dynamických typech . Jeden z posledních doplňků jazyka C++. Způsob, jak zjistit typ objektu za běhu. RTTI řeší otázky z předchozí obrazovky.
AR 2013/2014
Jazyk C++ II
3
RTTI RTTI můžeme použít pouze v rámci hierarchii tříd obsahujících virtuální funkce. Na podporu RTTI má jazyk C++ tři komponenty: Operátor dynamic_cast, Operátor typeid, Struktura type_info.
Potřebný hlavičkový soubor
. AR 2013/2014
Jazyk C++ II
4
Operátor dynamic_cast Generuje ukazatel na typ odvozený od ukazatele na základní typ, pokud to je možné. Pokud to není možné, tak vrátí hodnotu 0. Neodpovídá na otázku na jaký typ objektu ukazatel ukazuje, ale zda můžeme adresu objektu bezpečně přiřadit ukazateli na určitý typ.
AR 2013/2014
Jazyk C++ II
5
Operátor dynamic_cast Obecný výraz: dynamic_cast (pt) Pokud je odkazovaný objekt (*pt) typu Type nebo je přímo či nepřímo odvozen od typu Type: Konvertuje ukazatel pt na ukazatel na typ Type.
Pokud není: Výraz se vyhodnotí jako 0 (nulový ukazatel). AR 2013/2014
Jazyk C++ II
6
Operátor typeid Vrací hodnotu identifikující přesný typ objektu. Umožňuje určit, jestli jsou dva objekty stejného typu. Podobně jako operátor sizeof má dva typy parametrů: Název třídy, Výraz, který se vyhodnotí na objekt.
Operátor typeid vrací odkaz na objekt třídy type_info. AR 2013/2014
Jazyk C++ II
7
Třída type_info Třída type_info slouží jako návratový typ pro operátor typeid. Třída obsahuje následující členské metody: Before – zjišťuje, jestli je typ prvního parametru před druhým typem v implementaci. Name – vrací název třídy, Přetížený operátor ==, Přetížený operátor != .
AR 2013/2014
Jazyk C++ II
8
Třída type_info Typeid(Trida) == typid(*ukTrida) Se vyhodnotí na hodnotu true, pokud ukazatel ukTrida ukazuje na objekt třídy Trida. Jinak se vyhodnotí na hodnotu false. Pokud bude ukazatel ukTrida nulový, tak se vyvolá výjimka bad_typeid. AR 2013/2014
Jazyk C++ II
9
Třída type_info cout << “Nyní se zpracovává typ” << typeid(*ukTrida).name() << endl; if(typeid(TridaA).before(typeid(TridaB)) ) cout << “Třída A je před třídou B”; else cout << “Třída B je před třídou A”;
AR 2013/2014
Jazyk C++ II
10
Operátory přetypování Problém se zbytečnými a nebezpečnými způsoby přetypování. Z tohoto důvodu byly zavedeny nové čtyři operátory přetypování:
dynamic_cast, const_cast, static_cast, reinterpret_cast.
Místo obecného přetypování můžeme vybrat operátor vhodný pro konkrétní účel. AR 2013/2014
Jazyk C++ II
11
Operátor dynamic_cast dynamic_cast (výraz) Účelem tohoto operátoru je umožnit v hierarchii tříd přetypování na předka a znemožnit jiná přetypování. Takovéto přetypování je díky vztahu je bezpečné.
AR 2013/2014
Jazyk C++ II
12
Operátor const_cast const_cast (výraz) Slouží na přetypování konstantního ukazatele na nekonstantní a naopak. Dále také pro přetypování s modifikátorem volatile. Výsledek tohoto přetypování je chybný, jestliže se změní některý jiný aspekt tohoto typu (např. rozdílný typ). Operátor const_cast neumožňuje o změnu veličiny deklarované jako const. AR 2013/2014
Jazyk C++ II
13
Operátor const_cast Tabulka t1; const Tabulka * uT1 = &t1; ... Tabulka * uT2 = const_cast(uT1); //platne const Tabulka * uT3 = const_cast (uT1); //neplatne AR 2013/2014
Jazyk C++ II
14
Operátor static_cast static_cast (výraz) Příkaz je platný jenom tehdy, když lez názevtypu implicitně převést na stejný typ jako je výraz a obráceně. V jiných případech je přetypování chybné. Umožňuje přetypovat v opačném směru a to přetypovat na potomka z předka. AR 2013/2014
Jazyk C++ II
15
Operátor static_cast BTrida bInst; OTrida oInst; ... BTrida * pb = static_cast< BTrida *> (& oInst); //platné přetěžování na předka OTrida * pl = static_cast< OTrida *> (& bInst); //platné přetěžování na potomka AR 2013/2014
Jazyk C++ II
16
Operátor reinterpret_cast reinterpret_cast < název-typu> (výraz) Operátor reinterperet_cast je určený pro riskantní přetypování. Nedovoluje odstranit modifikátor const, ale dovoluje ostatní nebezpečné přetypování. Obvykle se toto přetypování používá při nízkoúrovňovém, implementačně závislém programování a nebývá přenositelná. AR 2013/2014
Jazyk C++ II
17
Operátor reinterpret_cast struct dat {short a; short b }; long hodnota – 0xA224B118; dat * pd = reinterpret_cast (& hodnota); cout << pd->a; //zobrazí první dva bajty hodnoty
AR 2013/2014
Jazyk C++ II
18
Operátor reinterpret_cast Operátor reinterpret_cast ale neumožní skoro vůbec nic. Můžeme ho využívat pro přetypování ukazatele na celé číslo, které je tak dlouhé, aby se do něj náš ukazatel vešel, avšak nemůžeme přetypovat na kratší celé číslo ani na číslo v pohyblivé řadové čárce. Dalším omezením je, že nemůžeme přetypovat ukazatel na funkci na ukazatel na data a nefunguje to ani naopak. AR 2013/2014
Jazyk C++ II
19
Literatura PRATA, Stephen. Mistrovství v C++. 3. aktualiz. vyd. Překlad Boris Sokol. Brno: Computer Press, 2007, 1119 s. ISBN 978-80-251-1749-1.
AR 2013/2014
Jazyk C++ II
20