dynamic_cast<> 의 bad_cast exception을 이용해서 type 매칭검사를 하셨나 보네요.
VC++ 에서는 RTTI 를 위해서 /GR 컴파일옵션을 활성화하여야 하며 /GR- 가 디폴트입니다. 프로젝트 등록정보에서 컴파일옵션으로 /GR을 추가하여 주시고, base class에는 최소한 하나의 virtual class가 있어야 하므로, 다음과 같이 해주시면 됩니다.
#include <iostream>
class Edge {
virtual void prn() {}
};
class CurvedEdge : public Edge {};
int main() {
Edge* pEdge = new CurvedEdge();
assert(typeid(pEdge) == typeid(Edge*));
assert(typeid(*pEdge) == typeid(CurvedEdge));
std::cout << typeid(pEdge).name() << std::endl;
std::cout << typeid(*pEdge).name() << std::endl;
return 0;
}
뉴스그룹에 typeid 와 dynamic_cast 의 속도에 대한 토론이 있는데, 중간에 두 연산자의 차이점에 대해서 잘 설명을 해 놓았습니다. 구글 뉴스그룹에서 "Performance: typeid() vs dynamic_cast" 를 검색하시면 나올겁니다. (URL이 붙여 넣기에 좀 길군요 ;-) )
Quote:
If you use typeid, you are comparing two exact types. OTOH, dynamic_cast has to check for classes in the whole hierarchy (if required) and adjust the pointer so that it points the proper sub-object within the original pointer. (The latter comes into picture for multiple inheritance, usually.
vc++ 메뉴얼에 typeid 연산자는 const type_info& 를 반환 한다고 되어 있어서 디버거에서 결과값을 확인해보니, 각각 부모 클래스와 자식 클래스의 타입 정보를 가지고 있습니다.
const type_info& a = typeid(pEdge);
const type_info& b = typeid(CurvedEdge*)
assert (a != b);
내친김에 (정말 오랫만에) C++에 관한 명저 "C++ FAQs (2nd Ed)" 까지 뒤져보았는데, 역시나 간결하면서도 심도있게 설명하고 있네요. 기회되면 한번 읽어보셔도 좋을 것 같습니다.
*pEdge 이렇게 한번 해보세요..[code:1]assert&#
*pEdge 이렇게 한번 해보세요..
g++에서는 되는군요..
고작 블로킹 하나, 고작 25점 중에 1점, 고작 부활동
"만약 그 순간이 온다면 그때가 네가 배구에 빠지는 순간이야"
음... 참조형으로 고쳐서 해봐도 안되고 fehead님 말씀대로 해봐도
음... 참조형으로 고쳐서 해봐도 안되고 fehead님 말씀대로 해봐도 안되는군요. VC++이 이 기능을 제대로 지원하지 못하나봐요. 결국에는 그냥 dynamic_cast를 이용해서 해결하기는 했는데 한참 삽질했네요.
Heejoon Lee
dynamic_cast<> 의 bad_cast exceptio
dynamic_cast<> 의 bad_cast exception을 이용해서 type 매칭검사를 하셨나 보네요.
VC++ 에서는 RTTI 를 위해서 /GR 컴파일옵션을 활성화하여야 하며 /GR- 가 디폴트입니다. 프로젝트 등록정보에서 컴파일옵션으로 /GR을 추가하여 주시고, base class에는 최소한 하나의 virtual class가 있어야 하므로, 다음과 같이 해주시면 됩니다.
#include <iostream> class Edge { virtual void prn() {} }; class CurvedEdge : public Edge {}; int main() { Edge* pEdge = new CurvedEdge(); assert(typeid(pEdge) == typeid(Edge*)); assert(typeid(*pEdge) == typeid(CurvedEdge)); std::cout << typeid(pEdge).name() << std::endl; std::cout << typeid(*pEdge).name() << std::endl; return 0; }결과
아하 base class에 가상 함수가 하나도 없어서 그랬군요. 고맙습니
아하 base class에 가상 함수가 하나도 없어서 그랬군요. 고맙습니다. ^^
지금은 dynamic_cast에서 캐스팅이 제대로 되지 않을 경우 NULL 포인터를 리턴한다는 사실을 가지고 타입을 판별하고 있는데 이것과 typeid를 쓰는 방법 둘 중에 더 권장할 만한 방법은 어느걸까요?
음... 그리고 dynamic_cast와 typeid가 타입을 판별하는 방식이 서로 다른 모양이네요. base class에 가상 함수가 있고 없고에 따라 다른 걸 보면 typeid는 virtaul function table을 쓰는건가요?
Heejoon Lee
올려주신 코드에서 assert가 fail 하는 것이 맞는 것 같습니다.
올려주신 코드에서 assert가 fail 하는 것이 맞는 것 같습니다.
뉴스그룹에 typeid 와 dynamic_cast 의 속도에 대한 토론이 있는데, 중간에 두 연산자의 차이점에 대해서 잘 설명을 해 놓았습니다. 구글 뉴스그룹에서 "Performance: typeid() vs dynamic_cast" 를 검색하시면 나올겁니다. (URL이 붙여 넣기에 좀 길군요 ;-) )
vc++ 메뉴얼에 typeid 연산자는 const type_info& 를 반환 한다고 되어 있어서 디버거에서 결과값을 확인해보니, 각각 부모 클래스와 자식 클래스의 타입 정보를 가지고 있습니다.
const type_info& a = typeid(pEdge);
const type_info& b = typeid(CurvedEdge*)
assert (a != b);
내친김에 (정말 오랫만에) C++에 관한 명저 "C++ FAQs (2nd Ed)" 까지 뒤져보았는데, 역시나 간결하면서도 심도있게 설명하고 있네요. 기회되면 한번 읽어보셔도 좋을 것 같습니다.
Jeongkyu Kim
OpenOffice.org Korean community lead
Official website http://ko.openoffice.org
Community forum http://oooko.net/
Personal blog http://oooko.net/gomme
[quote="wafe"]아하 base class에 가상 함수가 하나도
위에서 dynamic_cast를 썼다고 하시길래 다형적인(기초 클래스에 가상함수가 있는)
클래스라고 생각했는데 그게 아니었습니까? 다형적이 아닌 클래스에서
dynamic_cast를 쓰면 컴파일 에러가 날 텐데요. :shock:
dynamic_cast가 유연성이나 확장성에서 더 유리하므로 일반적으로는 이것을
많이 씁니다. typeid는 "정확한" 타입을 알아야 할 때 쓰고요.
struct S { virtual ~S(); }; struct T : public S { }; T t; assert(dynamic_cast<S*>(&t)); assert(typeid(S*) != typeid(&t));아니오. typeid는 클래스형뿐만 아니라 내장형에서도 동작합니다.
[quote="doldori"]위에서 dynamic_cast를 썼다고 하
실제로 프로젝트에서 사용하는 코드는 다형적인 클래스인데, typeid가 제대로 동작하는지 테스트 해보려고 간단히 짠 코드에서는 그렇지 않았거든요. 가상 함수가 있고 없고에 별 차이가 있겠냐고 생각했기 때문에...
사실 "다형적"이라는 게 무슨 말인지 아직까지 몰랐어요. :oops:
테스트 코드를 짤 때도 뭣좀 알고 짜야겠네요. ㅜ.ㅜ
Heejoon Lee
댓글 달기