2011-12-12 4 views
32

상속을 가상 메서드없이 수행 할 수 있습니까? 컴파일러는 다음 코드가 다형성이 아니라고 말합니다.클래스가 다형성이 아니기 때문에 다운 캐스트 할 수 없습니까?

예 :

우리가 B 객체에 A 개체에서 다운 캐스트하려고하는 다른 클래스에서
Class A(){ 
    int a; 
    int getA(){return a;}; 
} 


Class B(): A(){ 
    int b; 
    int getB(){return b;}; 
} 

:

A *a; 
B *b = dynamic_cast<B*>(a) 

그러나 이것은 다음과 같은 오류 제공 :

cannot dynamic_cast ... (source type is polymorphic) 
+1

'a'는 포인터가 아닙니다. 이 코드가 코드에 어떻게 있습니까? – littleadv

+0

죄송합니다. 실제로는 포인터입니다. – wbarksdale

+0

그리고 컴파일 시간 또는 실행 시간 오류입니까? 실행 시간, 다음 IMHO 예상 된 동작. – littleadv

답변

56

구문 오류가 아닌 내구성, 당신은 수 없습니다 dynamic_cast 비 다형성 유형 static_cast은 실제로 대상 유형의 객체라는 것을 알고있는 경우이 경우 사용할 캐스트입니다.

이유 : static_cast은 기본적으로 컴파일러가 컴파일 타임에 "출력을 캐스팅 할 수 있습니까?" 포인터 (또는 참조)의 상속 계층 구조를 위로 또는 아래로 캐스팅하는 경우에 사용할 수 있습니다. 그러나 컴파일 타임에만 검사가 수행되며 컴파일러는 사용자가 수행중인 작업을 알고 있다고 가정합니다.

dynamic_cast은 포인터 또는 참조 캐스트의 경우에만 사용할 수 있으며 컴파일 시간 검사 외에 캐스트가 합법적인지 추가 런타임 확인을 수행합니다. 문제의 클래스가 최소한 1 개의 가상 메소드를 가져야 만 컴파일러가 RTTI를 지원할 경우이 추가 검사를 수행 할 수 있습니다. 그러나 문제의 유형에 가상 메소드가 없으면 사용할 수 없습니다.

가장 간단한 경우와 같이 포인터를 전달하는 경우에는 기본 클래스의 소멸자를 가상으로 만드는 것이 좋습니다. 동적 캐스트를 사용할 수있을뿐만 아니라 기본 클래스 포인터가 삭제 될 때 적절한 소멸자가 호출되도록 허용합니다.

+0

지식에 대해 감사드립니다. 그게 효과가 있었어. – wbarksdale

2
A a; 
B *b = dynamic_cast<B*>(a) 

여기서 a는 개체이고 b는 포인터입니다.

실제로 upcasting 및 downcasting은 모두 C++에서 허용됩니다. 그러나 다운 캐스팅을 사용할 때는 다음 두 가지 사항에주의해야합니다. 1 수퍼 클래스에는 적어도 하나의 가상 메소드가 있어야합니다. 2 수퍼 클래스는 서브 클래스보다 "작다"때문에 메모리 객체를 신중하게 사용해야합니다.

4

예, 비 다형성 유형의 dynamic_cast는 허용되지 않습니다. 기본 클래스는 적어도 하나의 가상 메소드를 가져야한다. 그때 만 그 클래스는 다형성 (polymorphic)이라고 부를 수 있습니다.

이 문서에서는 비슷한 예를 설명 : http://www.cplusplus.com/doc/tutorial/typecasting/

+0

Dave는 좋은 대답을했습니다. 나는 그의 직위에 대해 논평 할 권한이 없다. 그래서 나는 여기서 논평하고있다. –

18

성공적 dynamic_cast는 연산자를 적용 할 run-time type information (RTTI)위한 클래스에서 적어도 하나의 가상 방법이 필요합니다.

11

그냥 소멸자를 가상으로 만듭니다 (항상 안전을 위해 모든 클래스에 대해 수행).

+7

어떤 클래스도 아니고 기본 클래스로 의도 된 클래스의 경우 – ParokshaX

관련 문제