2012-08-12 5 views
1

파생 클래스와 기본 클래스에 대한 캐스팅 포인터가 실제로 어떻게 작동하는지 궁금합니다. 다형성 : 런타임 캐스팅 포인터

struct A {}; 
struct B : A {}; 

// Boxing a pointer to an instance of B 
void* p = new B(); 

지금, let's 내가 포인터 p를 통해 가능 회원이나 메서드에 액세스하고 싶은 말은 : 다음은 예입니다.

A* a1 = (A*)p; 
A* a2 = (A*)((B*)p); 

어느 쪽이 맞습니까? 전혀 차이가 있습니까?
이 주제에 대한 추가 정보를 어디에서 얻을 수 있는지 말해 줄 수 있습니까?

+1

당신이 C++를 사용하는 경우, 다음 스타일 캐스트 C++를 선호한다. – iammilind

+1

여기에는 아무것도 박스가 없습니다. – Puppy

+0

필자가 보게되는 유일한 미묘한 차이점은 두 번째 캐스트에서는 두 개의 임시 포인터 개체가 생성되는 반면 첫 번째 개체는 단 하나의 포인터 개체라는 점입니다. P –

답변

1

이 경우 실제로는 차이가 없습니다.

하지만있을 수 차이 if there is multiple inheritance :

#include <cstdio> 

struct A { int x; }; 
struct B { int y; }; 

struct C : B, A {}; 

int main() { 
    void* c = new C(); 
    printf("%p\n", c);    // 0x1000 
    printf("%p\n", (A*) c);  // 0x1000 
    printf("%p\n", (A*) ((C*) c)); // 0x1004 
    return 0; 
} 

또는 서브 클래스 가상 메소드를 가지고 있지만, 부모가 수행되지 [1] 가상 상속 을 사용하는 것을 포함 [2]한다.

표준에서는 OP에서 C 스타일의 캐스트 인 which in this case is equivalent to static_cast을 사용합니다.

캐스팅 서열 B*void*B*A*는 §5.2.9 [expr.static.cast]/(13)에 의해 필요에 따라 처음 두 캐스트 같은 포인터를 다시 반환하는 경우, 유효하고, 마지막으로 주조 작업이며 포인터 변환 §4.10 [conv.ptr]/3. 물론, 결과는 §5.2.9/13 ☺에 정의되지 않은 때문에

그러나, 캐스팅 순서는 B*void*A* 실제로 정의되지 않은 결과를 제공 할 것입니다.


[1]

는 :

#include <cstdio> 

struct A { int x; }; 
struct C : A { virtual void g() {} }; 

int main() { 
    void* c = new C(); 
    printf("%p\n", c);    // 0x1000 
    printf("%p\n", (A*) c);   // 0x1000 
    printf("%p\n", (A*) ((C*) c)); // 0x1008 
    return 0; 
} 

[2] :

#include <cstdio> 

struct A { int x; }; 
struct C : virtual A {}; 

int main() { 
    void* c = new C(); 
    printf("%p\n", c);    // 0x1000 
    printf("%p\n", (A*) c);   // 0x1000 
    printf("%p\n", (A*) ((C*) c)); // 0x1008 
    return 0; 
} 
+3

Ewwww. 'printf', 정말로? – Puppy

+1

답변 해 주셔서 감사합니다. 나는 당신이 당신의 포스트에서 묘사하는 것을 이해한다고 생각합니다. 제 목적으로는 가능합니다. –

+0

@DeadMG :''그게 다야. – kennytm