안녕하세요. BlockDMask입니다. 즉 타입을 알아올 때 사용. <목차> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include<iostream> #include<typeinfo> using namespace std; int main() { auto num = 10; auto str = "BlockDMask"; const std::type_info& info1 = typeid(num); const std::type_info& info2 = typeid(str); cout << info1.name() << endl; cout << info2.name() << endl; return 0; } | cs |
이런 식으로. name() 멤버 함수로 접근을 하면 데이터의 현재 타입을 반환해줍니다.
2. C++ RTTI 기술을 사용한 예제
2-1) RTTI, typeid를 통해서 타입을 조사하는 방법
타입을 조사하는 방법
이렇게 typeid를 통해서 런타임 중에 데이터의 타입을 알아낼 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include<iostream> #include<typeinfo> using namespace std; int main() { auto num = 200; const std::type_info& info1 = typeid(num); const std::type_info& info2 = typeid(int); // type_info 에 담아서 사용 if (info1.name() == info1.name()) { cout << "num == int" << endl; } // typeid 바로 사용 if (typeid(num) == typeid(int)) { cout << "num == int" << endl; } return 0; } | cs |
두 경우 모두 "num == int" 이 결과가 나옵니다.
더 간단한 typeid(num) == typeid(int)를 사용하는 게 편하겠죠
2-2) RTTI, typeid와 클래스 상속 예제
실제 RTTI를 우리가 알게 모르게 쓰고 있었던 게 있습니다.
바로 dynamic_cast인데요. 이 dynamic_cast에서 프로그램 실행 중에 다운 캐스팅을 할 때 RTTI 기술을 이용해서 사용한다고 하네요.
원래 RTTI 목적이 프로그램 실행 중에 실제 타입을 알아오는데 쓰이려고 만들어진 것이기 때문에 dynamic_cast는 아주 적절하게 해당 기술을 이용했다고 생각이
듭니다.
Parent* pParent = new Child();라는 클래스가 있다고 할 때 부모 클래스(Parent), 자식 클래스 (Child)라 하겠습니다.
이럴 때 실제 pParent가 가리키고 있는 객체가 Child라는 것을 알 수가 없습니다. 그렇기 때문에 RTTI 기술을 사용해서 실제 객체가 무엇인지 알아서 판단을 해줄 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include<iostream> #include<typeinfo> using namespace std; class Parent { public: Parent() {} virtual ~Parent() {} }; class Child : public Parent { public: Child() {} }; int main() { // 부모 클래스 선언 Parent* pParent = new Parent(); cout << typeid(pParent).name() << endl; // 다운 캐스팅 Child* pChild = dynamic_cast<Child*>(pParent); cout << typeid(pChild).name() << endl; return 0; } | cs |
이렇게 다운 캐스팅이 정상적으로 되는 것을 볼 수 있습니다. 다운 캐스팅이 되는 이유는 RTTI 기술 덕분입니다.
좀 더 추가적으로 이야기하자면 위 예제를 보면 부모 클래스에 가상 함수가 있습니다.
만약 가상 함수가 없다면 어떻게 될까요? (위 예제에서 virtual ~ 소멸자를 지우고 프로그램을 실행시켜 보세요.)
그렇게 되면 실제 dynamic_cast가 되지 않는 것을 볼 수 있습니다.
그 이유는 RTTI
정보는 가상 함수가 사용된 클래스에 한해서만 정보가 유지됩니다.
그렇기 때문에 부모 클래스에서 virtual이 삭제되면 제대로 동작하지 않게 됩니다.
그런데 어차피
우리가 보통 부모 클래스를 선언하고 자식 클래스를 만들게 되면, "소멸자는 가상 함수로 만들어야 한다"라는 말을 듣지 않습니까? 그렇습니다. 정상적으로 "특정 클래스를 상속받는다, 상속한다" 하면 소멸자에 virtual 키워드가 붙어있어야'만'합니다. 그렇기 때문에 대부분의 상황에서는 잘 동작할 것입니다.
이상으로 C++ RTTI에 대해서 알아보았습니다. 감사합니다.