RTTI

Z Wikipedie, otevřené encyklopedie
Skočit na: Navigace, Hledání

RTTI (Run-Time Type Information, tj. informace o typu za běhu) nebo Run-Time Type Identification (tj. typová identifikace za běhu) je v informatice technika používaná v programovacím jazyce C++, která odhaluje informaci o datovém typu objektu za běhu programu. RTTI může být aplikována jak na jednoduché datové typy (např. celá čísla, znaky), tak také na generické datové typy. Tato technika je specializací jazyka C++, která rozšiřuje obecný koncept techniky nazývané typová introspekce. Podobné techniky jsou ovšem známé i z jiných programovacích jazyků, jako je například Delphi (Object Pascal).

Zajímavostí pak je, že v původní implementaci jazyka C++ tato technika nebyla vložena, jelikož se její autor Bjarne Stroustrup domníval, že by byl mechanismus velmi často používán špatným způsobem.[1]

Vlastnosti[editovat | editovat zdroj]

Základními částmi RTTI v C++ jsou operace dynamic_cast<> a operátor typeid.

Tyto funkce pro zjištění datového typu za běhu programu umožňují bezpečnější přetypování či jinou manipulaci s datovými typy.

RTTI je dostupná pouze pro polymorfní třídy, což znamená, že třída musí mít nejméně jednu virtuální metodu. V praxi tato podmínka ovšem nepředstavuje žádný problém, jelikož základní třídy musí mít virtuální destruktor, tak aby objekty odvozených tříd mohli provést řádné vyčištění paměti, pokud jsou mazány pomocí ukazatele na základní datový typ.

RTTI je v některých kompilátorech pouze volitelnou součástí, programátor si tak může během procesu kompilace zvolit, jestli funkce bude nebo nebude obsažena. To může také způsobit zvýšení nároků na zdroje, v případě že je technika RTTI vložena ale není používána.

Ukázka v jazyce C++[editovat | editovat zdroj]

/* Ukazatel na objekt třídy předka může odkazovat na objekt libovolné třídy, která 
 * je z něj poděděna. RTTI lze použít ke zjištění jakého typu (některá z tříd 
 * dědící z předka) je objekt, na který je odkazováno ukazatelem předka.
 */
 
#include <iostream>
 
class Predek
{
public:
    Predek() { } 
    virtual ~Predek() { } 
 
    virtual void ahoj() 
    {
        std::cout << "Předek";
    }
};
 
class Potomek : public Predek
{
public:
    void ahoj() 
    {
        std::cout << "Potomek";
    }
};
 
int main()
{
    Predek* ukazatelPredek = new Potomek();
    Potomek* ukazatelPotomek = nullptr;
 
    //Zjištění zda ukazatel předka (ukazatelPredek) odkazuje na objekt třídy Potomek
    ukazatelPotomek = dynamic_cast<Potomek*>(ukazatelPredek);
 
    if (ukazatelPotomek != nullptr)
    {
        std::cout << "ukazatelPredek ukazuje na objekt třídy Potomek";
    }
    else
    {
        std::cout << "ukazatelPredek neukazuje na objekt třídy Potomek";
    }
 
    //Potřebný virtuální destruktor 
    delete ukazatelPredek;
    ukazatelPredek = nullptr;
 
    return 0;
}

Příklad ve kterém je RTTI použito k porovnání:

class Predek
{
public:  
    virtual ~Predek(){}
};
 
class Potomek : public Predek
{
public:
    Potomek() {}
    virtual ~Potomek() {}
 
    int porovnej (Potomek& ref);
};
 
int mojePorovnavaciMetodaSlouziciKSerazovani (Predek& ref1, Predek& ref2)
{
    Potomek& p = dynamic_cast<Potomek&>(ref1); //užití RTTI
    //Poznámka: Pokud se přetypování nepovede, RTTI umožňuje procesu vyhodit výjimku bad_cast exception
 
    return p.porovnej (dynamic_cast<Potomek&>(ref2));
}

Reference[editovat | editovat zdroj]

  1. Bjarne Stroustrup. A History of C++: 1979—1991 [online]. [cit. 2009-05-18]. S. 50. Dostupné online.  

V tomto článku byl použit překlad textu z článku Run-time type information na anglické Wikipedii.