|
한 서너달만에 답변을 쓰는군요. ^^;;
__classid는 원래 안시 C++에는 없는 "클래스(타입)에의 포인터"를 돌려주는 키워드입니다.
C++Builder에서 이런 키워드를 도입한 이유는 오직 오브젝트 파스칼(더 정확히는 VCL)과 상호
연동할 수 있게 하기 위해서입니다.
오브젝트 파스칼에는 클래스에의 포인터라는 타입이 존재합니다.
TMyComponentClass : class of TMyComponent;
이런 식으로 선언했던 것으로 기억합니다.
(뒤져보기 귀찮아서.. VCL 코드를 뒤져보면 수없이 나옵니다.)
이것은 C++에는 없는 오브젝트 파스칼만의 특징으로서, '변수'가 아닌 '클래스'에의 포인터입니다.
오브젝트 파스칼에서 이런 타입이 존재하는 이유는, 클래스타입을 함수의 인자로 넘겨줘야 할
경우가 있기 때문입니다.
이런 경우는 기본적으로는 컴퍼넌트를 생성할 때나 정적인 폼을 생성할 때처럼 새로운 타입을 동적으로
생성할 때 뿐입니다.
넘겨받는 함수쪽에서는 해당 타입 자체를 모르므로 해당 타입의 변수를 넘겨받을 수도 없고,
(함수의 인자 타입들은 코딩시에 다 결정되므로) 그러므로 클래스 타입의 레퍼런스를 넘겨줘서
넘겨받은 함수측에서 그것이 가리키는 새 타입을 인식할 수 있도록 하는 것입니다.
그러므로,
1. __classid(TAppLock)가 TMetaClass* TAppLock을 가리키는 것이 맞습니다.
2. TMetaClass* TAppLock 대신 __classid를 쓰는 것은 오브젝트 파스칼에서의 문법에 좀 맞춰주려는
의도일 뿐입니다. 그냥 TMetaClass* TAppLock라고 쓰셔도 됩니다.
3. 저도 확실히는 모르지만, 클래스는 그자체가 타입이지만 내장 타입(primitive)이 아니기 때문에
vtable에 그 타입에 대한 정보가 저장되는 것이 당연할 겁니다.
__classid는 일반적인 코딩에 쓸 일은 전혀 없습니다.
전에 상당히 특이한 방법을 쓰는 델파이 컴퍼넌트를 C++로 옮겼던 적이 있었는데, 저도 거기서 딱
한번 쓰고 난 이후로는 전혀 잊고 삽니다.
그럼...
궁그미 님이 쓰신 글 :
: 책에 __classid의 역할에 대해
:
: C++ Builder's representation of the Object Pascal class-reference type.
: The TMetaClass for a given class can be acquired by using the __classid operator.
: The Compiler uses the __classid operator to generate a pointer to the vtable
: (virtual table) for the given classname.
:
: 이렇게 설명되어 있는데요. 예로,
:
: RegisterComponentEditor(__classid(TAppLock), __classid(TAppLockEditor));
:
: 여기서,
:
: 1. __classid(TAppLock)가 TMetaClass* TAppLock라는 뜻인가요?
: 2. 그렇다면 TMetaClass* TAppLock로 안 쓰고 __class(TAppLock)로 쓰는 이유는 먼가요?
: 3. vtable를 가리키는 포인터를 생성한다고 했는데요. 저는 virtual function을 가지는
: 경우 이런 포인터가 생성된다고 알고 있었는데요. __classid 연산과 vtable과 무슨
: 관계가 있나요?
|