RTTI w C++

Opublikowane: 30/11/2014

w kategorii Zasoby.

RTTI (Run-Time Type Information) używane jest do wyłuskania informacji o typie danych w czasie uruchomienia programu. W C++ popularnym jest twierdzenie, że należy tego unikać, ponieważ zwalnia to przetwarzanie i można tego uniknąć. Popularny anty-wzorzec który można znaleźć w pytaniach od początkujących wygląda jak poniżej:

double obliczPowierznie(Ksztalt &ksztalt) {
{
   if (typeid(ksztalt) == typeid(Prostokat))
   {
     Prostokat *prost = dynamic_cast<Prostokat *>(&ksztalt);
     return prost->a * prost->b;
   } else {
   ...
   }   
}

W tym kodzie jest kilka braków:

  • nie będzie pracować z klasami które bazują na Ksztalt jeśli nie zostaną dodane w powyższym kodzie (łamie zasadę LSP)
  • używa RTTI (dynamic_cast zwalnia procesowanie)
  • zmusza Cię do zmiany "obliczPowierznie" za każdym razem gdy chcesz dodać nowy kształt (łamie zasadę OCP)

Lepsze rozwiązanie:

double obliczPowierznie(Ksztalt &ksztalt) {
{
   return ksztalt.podajPowierzchnie(); // podajPowierzchnie jest wirtualną funkcją zaimplementowaną w klasach pochodnych dla klasy Ksztalt
}

elementy RTTI

  • typeid: zwraca referencję do obiektu klasu type_info opisującego obiekt wejściowy, może być użyty do porównania typów obiektów
  • typeid(a).name(): zwraca nazwę klasy obiektu a
  • dynamic_cast: sprawdza czy podany obiekt może być skonwertowany do wybranej klasy i jeśli tak - zwraca skonwertowany obiekt
  • dynamic_pointer_cast (C++11): konwertuje typ sprytnego wskaźnika typu shared pointer

Nie całkiem RTTI

  • std::is_same (C++11): porównuje dwa typy - w czasie kompilacji
  • type_traits (C++11): kontrola cech podanego typu w czasie kompilacji
  • static_cast: konwertuje wartość do innego typu w czasie uruchomienia bez wykorzystania RTTI
  • static_pointer_cast (C++11): konwertuje shared_ptr z użyciem static_cast

Prezentacje

Zobacz również

Udostępnij

obserwuj