2012-07-18 3 views
1

다음 샘플 코드를 고려하십시오. 라인 1에서 static_cast 연산자를 사용한 안전하지 않은 캐스트가 왜 충돌하지 않습니까?

#include <iostream> 

using namespace std; 

class base 
{ 

    public: 
     void func() 
     { 
     cout << "base::func()" << endl; 
     } 

}; 

class derived : public base 
{ 
    public: 
     void func() 
     { 
     cout << "derived::func()" << endl; 
     } 

}; 

void dummy(base *bptr) 
{ 
    derived *dptr = static_cast<derived*> (bptr); 
    dptr->func(); 
} 

int main() 
{ 
    base bob1; 
    derived dob1; 

    dummy(&dob1); //Line1 
    dummy(&bob1); //Line2 
} 

는 I베이스 클래스 객체에 대한 포인터를 얻어 함수 dummy에 파생 클래스 객체의 주소를 전달하고있다. 따라서 이 dummy 인 것은 안전합니다.

Line2에서 기본 클래스 개체의 주소를 전달하려고합니다. 따라서 이 dummy 인 함수는 안전하지 않습니다.

그러나 코드를 실행하면 프로그램이 정상적으로 작동합니다. 나는 단어 not safe에 의해 프로그램이 런타임에 충돌해야한다고 생각했다. 그러나 충돌은 발생하지 않았습니다.

다음은 내가 얻는 결과입니다.

derived::func() 
derived::func() 

런타임에 프로그램이 중단되지 않은 이유는 무엇입니까?

+0

나쁜 코드는 좋은 코드보다 훨씬 이해하기 어렵습니다. –

+0

@ David : 자세히 설명해 주시겠습니까? –

+0

가능한 중복 http://stackoverflow.com/questions/2469013/should-static-castderived-base-pointer-give-compile-time-error – celavek

답변

9

정의되지 않은 동작은 아무 일도 일어나지 않을 수도 있음을 의미합니다.

내가 본 대부분의 컴파일러에서 NULL 포인터의 클래스 멤버에 액세스하지 않는 virtual 메서드를 호출하면 작동하지만 정의되지 않은 상태로 유지됩니다.

6

C++의 핵심 개념 중 하나는 입니다. 정의되지 않은 동작입니다. 동작이 정의되지 않은 동작을 수행하면 (예 : 캐스팅 된 유형의 객체를 가리 키지 않는 포인터를 정적 캐스팅하면 프로그램의 동작이 문자 그대로 정의되지 않습니다. 표준은 특정 동작을 정의하지 않습니다. 플랫폼은 특정 작업을 수행 할 필요가 없으며 표준에 따라 작동하는 것으로 보이는 모든 동작이 가능합니다.

이 정의되지 않은 동작은 정상적인 동작처럼 보이는 것을 자동으로 수행하는 것을 포함합니다. 세그먼테이션 결함 또는 기타 진단에 대한 보장은 없습니다.