Dupa cum am discutat si pe Yahoo, dynamic_cast e fix solutia care NU iti trebuie. In general RTTI-ul este incet cind lasi compilatorul sa-l faca, deoarece C++ permite ierarhii extrem de complicate, deci compilatorul trebuie sa se dea peste cap sa suporte toate cazurile. O scurta dezasamblare a codului generat de VC 2005 pentru dynamic_cast ne arata ca, pentru cazul banal in care clasele sint inrudite si ierarhia e liniara, se ruleaza aproape 200 de instructiuni, se apeleaza citeva functii si se fac vreo 6 accese la memorie (si toate sint cache miss-uri, probabil). Pentru cazurile mai complicate cu mostenire multipla sau virtuala sau alte timpenii se executa probabil niste mii de instructiuni (n-am mai avut rabdare sa numar).
In plus, dynamic_cast mai are citeva feature-uri minunate. Unul ar fi ca in viltoarea OOP-ului te poti trezi ca-l folosesti pe referinte. Evident, pentru referinte nu mai are cum sa returneze 0 cind clasele nu-s inrudite, asa ca va arunca o exceptie, lucru cu care te califici intr-o noua liga a campionatului de cod care n-are ce cauta in jocuri. Alt feature este:
Cod sursă:
class Base {};
class Child : public Base {};
class GrandChild : public Child {};
Base* b = new GrandChild;
Child* c = dynamic_cast((Child*))b; // paranteze duble in loc de mai mic mai mare, multumim softului paranoic de forum
if(c) { printf("c este Child"); }
Codul asta se va jura ca "c este Child", ceea ce e adevarat. Problema e cind vrei sa determini relatia stricta, ca atunci dynamic_cast nu mai are cum sa te ajute.
Solutia este, evident, sa bagi o functie virtuala care sa-ti returneze un int ce identifica clasa. Este mai simplu si MULT mai eficient. Nu exista scuze pentru folosirea lui dynamic_cast pentru RTTI, asta e genul de cod care te face sa pici interviuri la firmele de jocuri (sau ar trebui sa fie). dynamic_cast e obligatoriu cind faci cast-uri in ierarhii tembele cu mostenire virtuala, dar in general nu exista scuze nici pentru a folosi mostenirea virtuala.