RTTI, Run-Time Type Information'ın kısaltmasıdır. Çalışma zamanında tür bilgisinin elde edilmesi anlamına gelmektedir. Bunun için ilgili türlerin polimorfik olması gerekmektedir. Bir türün polimorfik olması için en az bir tane kendisinde veya base türünde virtual bir metodun tanımlanmış olması gerekmektedir. Her sınıfın (objenin degil) kendine özgü bir vtable'ı bulunmaktadır. Basit olarak vtable yapısı aşağıdaki gibidir.
Tür bilgisi vtable içerisinde yer aldığından dolayı böyle bir yapısal ilişki - zorunluluk olmaktadır. type_info değeri aşağıda da görebileceginiz üzere vtable içerisindedir.
C++ 'da RTTI mekanizmasının 3 farklı kullanım senaryosu vardir:
- typeid operatörü
- type_info sınıfı
- dynamic_cast işlemi
typeid ve type_info
typeid operatörü bir nesnenin dinamik tipini öğrenmek için kullanılır. Ve typeid operatörü, bir type_info nesnesini const bir referans olarak döndürür. Daha sonra ihtiyaca göre bu nesneyi diğerleriyle karşılaştırabilir veya türün ismini yazdırabiliriz.
dynamic_cast
Derleme zamanının aksine çalışma zamanında bir nesne hakkında type cast işlemi sayesinde tür hakkında bilgi almak için kullanılır. Polimorfik olmayan dillerde bu bilgiye gerek yoktur, çünkü tür her zaman derleme zamanında ve dolayısıyla çalışma zamanında bilinir. C++ gibi polimorfik türleri destekleyen bir dilde, türün derleme sırasında bilinmediği durumlar vardır. Bir pointer, temel sınıf türündeki bir nesneyi veya temel sınıftan türetilen herhangi bir sınıf türündeki bir nesneyi işaret edebilir. Bu nedenle RTTI ve dolayisiyla dynamic_cast ile çalışma zamanında tür hakkında bilgi alınmasına yardımcı olunur.
vtable layout
g++ icin -fdump-class-hierarchy flag değeri ile vtable (virtual function table) layout değerleri incelenebilir. Program derlenirse cpp dosyasi ile ayni isimde ama uzantı olarak .002t.class şekilde bir dosya oluşturulur. Içeriğine bakarsak :
c++filt aracı ile C++ symbolleri demangle edilirse asağıdaki gibi vtable'ın ikinci elemanı typeinfo 'ya ilişkin olduğu görülmektedir.
Note1 : type_info nesnelerinin copy constructor'ları yoktur. Bu nedenle bir containerda saklamak gibi yöntem doğrudan mümkün değildir. Bunun için sarmalayıcı bir sınıf yazarak mümkün hale gelebilmektedir.
Note2: Normalde RTTI, -fno-rtti flag değeri ile disable edilebilir. RTTI in en temel dezavantajlarından biri çalıştırılabilir kodun boyutunun büyümesidir. RTTI yalnızca belirli türler için devre dışı bırakmak/etkinleştirmek mümkün değildir. Etkinleştirildiğinde ise, RTTI hem yerleşik hem de polimorfik olmayan kullanıcı tanımlı türler için otomatik olarak oluşturulur. Bu da calistirilabilir kodun boyutunun cok büyümesine neden olmaktadır.