- C++ 자체도 일단은, RTTI를 지원한다. 하지만, 성능상의 이유로, Unreal이나, Unity는 내부에 자체적으로 RTTI가 구현이 되어있다. 내가 작성한 버전은, template과 static의 특성을 사용한다. static 변수는 한 번만 초기화되는 녀석이므로, 매크로를 이용하여, Type을 string으로 변환하여, static 메모리에 저장한다. 이후 RTTI가 요구되는 클래스에 매크로를 추가해 주고, RTTI가 필요할 때, template type deduction에 의해 RTTI가 가능해진다.
class RTTI
{
public:
virtual const size_t TypeIdInstance() const = 0;
virtual RTTI* QueryInterface(const size_t){
return nullptr;
}
virtual const RTTI* QueryInterface(const size_t) const{
return nullptr;
}
virtual bool Is(const size_t id) const{
return false;
}
virtual bool Is(const std::string& name) const{
return false;
}
template <typename T>
T* As(){
if(Is(T::TypeIdClass())){
return (T*)this;
}
return nullptr;
}
template <typename T>
const T* As() const{
if(Is(T::TypeIdClass())){
return (T*)this;
}
return nullptr;
}
};
#define RTTI_DECLARATIONS(Type, ParentType) \
public: \
static std::string TypeName() { return std::string(#Type); } \
virtual const size_t TypeIdInstance() const \
{ return Type::TypeIdClass(); } \
static const size_t TypeIdClass() \
{ static int d = 0; return (size_t) &d; } \
virtual RTTI* QueryInterface( const size_t id ) \
{ \
if (id == TypeIdClass()) \
{ return (RTTI*)this; } \
else \
{ return ParentType::QueryInterface(id); } \
} \
virtual const RTTI* QueryInterface( const size_t id ) const \
{ \
if (id == TypeIdClass()) \
{ return (RTTI*)this; } \
else \
{ return ParentType::QueryInterface(id); } \
} \
virtual bool Is(const size_t id) const \
{ \
if (id == TypeIdClass()) \
{ return true; } \
else \
{ return ParentType::Is(id); } \
} \
virtual bool Is(const std::string& name) const \
{ \
if (name == TypeName()) \
{ return true; } \
else \
{ return ParentType::Is(name); } \
}
'삽질 > COM' 카테고리의 다른 글
Trace (0) | 2020.11.13 |
---|---|
Verify (0) | 2020.11.13 |
COM study note 8 IUnknown C# 버전 (0) | 2020.10.30 |
COM study note 8 IUnknown 이식 (0) | 2020.10.30 |
COM study note 7 (0) | 2020.10.29 |