2010-03-20 7 views
2

컴파일 f이 작동하지만 g을 컴파일하면 오류가 발생하여 실패합니다.static_cast 없이는 실패하는 이유는 무엇입니까?

왜 이런 일이 발생합니까?

class A { 
public: 
    A() {} 
}; 

class B : public A { 
public: 
    B() {} 
}; 

void f() { 
    A* a = new A(); 
    B* b = static_cast<B*>(a); 
} 

void g() { 
    A* a = new A(); 
    B* b = a; 
} 
+2

잠시만 기다려주세요 ... 여기에 질문을 게시했습니다. http://stackoverflow.com/questions/2483227/why-the-function-from-immediate-parent-is-called-and-not-from-grandparent -class 10 minutes ago .... .... 아무도 응답하지 않으면, 똑같은 것을 다시 게시하지 마라. 닫기 투표! – t0mm13b

+5

@ Tommieb75 : 이 두 가지는 서로 다른 질문입니다. 내가 두 개의 다른 Q를 올렸습니다. 의도하지 않은 중복이있는 경우. – sandeep

+0

'static_cast '는 컴파일러에게 "나를 믿어 라, 나는 이것이 실제로 B *임을 안다."라고 말한다. 이 상황에서 컴파일러가 거짓말을한다는 의미입니다. – Bill

답변

3

글쎄, 네. 수행 :

B* b = new A(); 

안전하지 않습니다. 결국 A 객체에 대한 B 포인터로 끝납니다. 당신은 객체의 B 부분을 구성하지 않습니다. 귀하의 개체는 "슬라이스"입니다. 한편

...

A* a = new B(); 

은 ... 잘 될 것입니다.

+0

B * b = new A(); 컴파일하지 않습니다 ... A * a = new A(); B * b = static_cast (a); 컴파일 ... 나는 똑같은 일을하려하고있다. – sandeep

+0

'B * b = a;'는 올바르지 않기 때문에 컴파일되지 않습니다. 일반적으로 컴파일러는'a'가 실제로'B' 타입의 객체를 가리키는 지 알 수 없으므로 암시 적 변환을 허용하지 않습니다. 'static_cast'는 변환을 강제하는 방법이지만 객체가'B' 타입이 아니라면''b''를 사용하면 정의되지 않은 동작을하게됩니다. –

1

포인터를 A *에서 B *로 변환하려고합니다. 나는 당신이 성취하려는 것을 확신하지 못합니다. 그러나 B *는 A *에서 파생 되었기 때문에 다른 방법으로는 유효하지 않습니다. 아마도 당신은 다음과 같은 것을하려고합니다 :

int main() 
{ 
///The above code compiles while if I replace above two line in main with below assignment it gives error. 
    A *a=new A(); 
    A * b=new B(); 

} 
0

기본 클래스는 암시 적으로 파생 클래스로 변환 될 수 없습니다. 이 점을 고려하십시오

class A { 
    public: int x; 
}; 
class B : public A { 
    public: int y; 
}; 
B* b = new A; // assume it works, so 4 bytes is allocated and initialized. 
b->y;   // bam! accessing unallocated region. 
1

예, 파생 클래스 포인터 유형에 기본 클래스를 지정하려는 경우 오류가 발생합니다. 아니요, 명시 적으로 포인터 유형을 캐스팅하면 오류가 발생하지 않습니다. 왜냐하면 C++에서는 원할 경우 발에서 자신을 쏠 수 있기 때문입니다.

정확하게 당신을 당황하게하는 것은 무엇입니까? 아니면 귀하의 코드로 무엇을 성취하려고합니까?

4

static_cast은 잠재적으로 안전하지 않은 변환을 강제합니다. a 실제로 B 객체의 기본 클래스 하위 개체이었던 A 객체가 가리키는 경우

B* b = static_cast<B*>(a); 

그러나 이것은 그렇지 않습니다 유효 할 것이다. 캐스트가 변환을 강제합니다.

B* b = a; 

여기에는 캐스트가 없으며 기본 클래스 포인터에서 파생 클래스 포인터로의 암시 적 변환이 허용되지 않습니다. 파생 클래스 객체는 항상 기본 클래스 하위 객체를 포함하지만 모든 기본 클래스 인스턴스가 특정 파생 클래스 유형의 하위 객체가 아니므로 파생 클래스에 대한 포인터는 기본 클래스에 대한 포인터로 항상 변환 될 수 있습니다.

+1

이 질문을 삭제 취소하려는 사람에게 : 나는 그것이 오류로 폐쇄되었고 아마도 소음으로 삭제되었다고 생각합니다. 사용자가 두 개의 질문을 연속적으로 게시했으며 서로의 중복이라는 잘못된 주장이있었습니다. 질문의 내용을 읽는다면 그렇지 않습니다. 이 질문은 * 단언 할만한 가치가있을 수 있지만 단언 할만한 복제물의 정확한 복제본이 아니기 때문에 분명히 아닙니다. –

관련 문제