به این کد دقت کنید :
#include <iostream>
using namespace std;
struct A
{
virtual char* Foo (void) { return "Class A"; }
}*a;
struct B : A
{
virtual char* Foo (void) { return "Class B"; }
};
void Test (B* b)
{
cout<<"B* b is : "<<typeid(*b).name()<<endl;
b = dynamic_cast<B*>(b);
if(b){
cout<<"Succeed"<<endl;
}
else
cout<<"Failed"<<endl;
}
int main (void)
{
a = new A;
Test((B*)a);
getchar();
return 0;
}
شما نمیتونید مطما باشید که همیشه پارامتری که به تابع Test فرستاده میشود یک اشاره گر از یک B واقعی هست. یعنی ممکن است ریخت واقعی اشاره گری که به Test فرستاده میشود از یک نوع دیگه باشد.
برای همین شما باید این اطمینان رو با استفاده از dynamic_cast بدست بیارید.
دلیلش هم اینه که dynamic_cast در زمان اجرا (Run-Time) با استفاده از RTTI میتونه دقیقا نوع یک اشاره گر رو بررسی کنه و مانع از Cast های اشتباه بشه.
برای استفاده از dynamic_cast و شما باید قابلیت RTTI رو در کامایلرتون فعال کنید که به صورت پیش فرض در بیشتر کامپایلر ها فعال هست.
مثلا در کد بالا اشاره گر a به تابع Test فرستاده میشه ، و تابع Test با استفاده از dynamic_cast متوجه میشه که پارامتر فرستاده شده یک B واقعی نیست.
حالا اگر شما اشاره گر a رو به این صورت ;a = new B ایجاد کنی و به تابع تست ارسال کنی ، تابع تست متوجه میشه که این اشاره گر یک B واقعی است.
درکل بعضی از اشاره گرها در طول برنامه به ریخت های متفاوتی تبدیل میشوند (Poylymorphism) که شما با استفاده از dynamic_cast و typeid میتونید ریخت حال حاضر این اشاره گر ها رو در زمان Run-Time بررسی کنید.