|
검색해보니 이런 글이 있군요.
"예를 들면, typeid(*Sender).name()는 "System::TObject"를 돌려준다."
typeid() <-- 이게 문의하신 주 내용과 관련된 부분이네요.
------
6. as, is 연산자와 dynamic_cast
Delphi에서는 안전하게 type cast를 하기 위해 as연산자를 사용한다. 예를 들면 다음과 같이 사용한다.
procedure TForm1.Button1Click(Sender: TObject);
begin
try
(Sender as TButton).Caption := 'Click detected';
except on E: EInvalidCast do
Application.ShowException( E );
end;
end;
무효한 캐스트를 행하면 EInValidCast 예외가 발생하고, 오브젝트는 부당한 캐스트로 부터 보호된다. C++ Builder에서는 dynamic_cast를 사용해 오브젝트를 안전하게 캐스트할 수 있다. dynamic_cast는 캐스트하는 형 및 오브젝트를 건네준다.
부당한 캐스트가 행해진 경우 dynamic_cast는 실패하고 NULL을 돌려준다. 예를 들면 위의 예를 C++ Builder에서 기술하면 다음과 같이 된다.
void __fastcall TForm1::Button1Click(TObject* Sender)
{
TButton* btn = dynamic_cast<TButton*>(Sender);
if(btn) btn->Caption = "Click detected";
}
또, Delphi에서는 오브젝트의 형이 지정된 형에 속하는가를 확인하기 위해 is 연산자를 상요한다. is연산자는 Boolean을 돌려주며 다음과 같이 사용한다.
procedure TForm1.Button1Click(Sender: TObject);
begin
if Sender is TButton then
TButton(Sender).Caption := 'Click detected';
end;
end;
C++ Builder에서는 dynamic_cast를 사용해 결과가 NULL인지를 확인할 수 있기대문에 is연산자에 대해서 dynamic_cast를 사용한다. C++에서는 typeid를 사용해 클래스의 특정을 행할 수 있지만, VCL 클래스는 Delphi의 클래스(__declspec(delphiclass)로서
정의된 클래스)에는 사용할 수 없다.
예를 들면, typeid(*Sender).name()는 "System::TObject"를 돌려준다.
struct __rtti A
{
__fastcall A() {}
virtual __fastcall ~A() {}
}
struct __rtti B: public A
{
__fastcall B() {}
virtual __fastcall ~B() {}
}
static const char* getClassName(A* a)
{
return typeid(*a).name();
}
void foo()
{
getClassName(new B);
}
위의 예의 경우 getClassName는 "B"를 돌려주지만, 클래스 A를 TObject로부터
계승한 클래스로서 선언하면 "A"를 돌려준다.
|