Published 2022. 7. 15. 16:52
  • 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
복사했습니다!