2015-01-22 1 views
1

나는이 같은 클래스 BaseDerived이했습니다이상한 행동은

class Base 
{ 
public: 
}; 

class Derived : public Base 
{ 
public: 
}; 

및 주요 기능 :

int main() 
{ 
    Base* ptr = new Derived; 

    std::cout << typeid(*ptr).name() << endl; 

    delete ptr; 

    system("pause"); 
} 

프로그램 출력은 내가이 표시됩니다 예상 class Base을 보여줍니다 class Derived. 그러나 Base 클래스에 가상 메서드를 추가하면 출력 결과는 class Derived입니다!

왜 RTTI에 최소한 하나의 가상 메소드가 필요한가요?

+0

[Typeid not functionaling correcly] (http://stackoverflow.com/q/18147864/1708801)의 복제본처럼 보이지만 기본적으로 가상 메서드를 추가하면 원하는 결과를 얻을 수 있습니다. –

+1

컴파일러를 작성했다면 어떻게'typeid'를 구현하겠습니까? 아마 숨겨진 가상 메서드로 그것을 할 것입니다. 그러나 클래스에 가상 메서드가 없으면 (따라서 vtable도 없음)이 방법은 불가능합니다. 나는 이것을 수용하기 위해 C++ 스펙이 작성되었다고 생각한다. –

+0

'ptr'을'Base *'로 선언했습니다. 그 밖의 무엇을 기대합니까? 런타임 유형 검사가있는 Java와는 다릅니다. C++은 전적으로 정적입니다. – texasbruce

답변

4

언어 사양에 그렇게 나와 있기 때문에. RTTI는 다형성 타입에서만 작동합니다. 즉 가상 함수가있는 유형입니다. 다른 유형의 경우 typeid은 해당 인수의 정적 유형에 대한 유형 정보를 리턴합니다.

실행 시간 비용이 필요합니다 (일반적으로 각 개체에 가상 디스패치와 RTTI를 모두 지원하는 클래스 별 메타 데이터에 대한 포인터가 있음). 만약 당신이 RTTI를 사용하길 원하든 원하지 않든 모든 유형에 대해 그 가격을 지불해야한다면 수치 스러울 것입니다.

0

Too long for a comment.

1)는 STD를 참조 :: 개체 유형을 나타내는 유형의 type_info. 유형이 참조 유형 인 경우 결과는 참조 된 유형을 참조합니다.
2)
표현식 발현를 검사

a) 식 다형성 형태 (즉, 선언하는 적어도 하나 개의 가상 함수를 상속 클래스)의 개체를 식별하는 glvalue 식은 경우 을 typeid expression은 표현식을 평가 한 다음 표현의 동적 유형을 나타내는 std :: type_info 객체를 나타냅니다. 평가 된 식의 결과가 null 포인터 인 경우 std :: bad_typeid 형식의 예외 또는 std :: bad_typeid에서 파생 된 형식이 throw됩니다. 식 다형성 형태의 glvalue 표현이 아니라면

b) 는 유형 ID는 표현식을 평가하지 않으며, STD는 ::이 식별 발현의 정적 타입을 나타내는 오브젝트있는 type_info. Lvalue-to-rvalue, 배열 대 포인터 또는 함수에서 포인터로의 변환이 수행되지 않습니다.

따라서 클래스가 다형성이고 다른 클래스는 그렇지 않기 때문에 동작이 예상됩니다.