2009-12-02 4 views
1

주소를 포함하는 정수 타입을 실제 포인터 유형으로 변환해야합니다. 다음과 같이 나는 reinterpret_cast 사용할 수 있습니다C++ : 정수를 포인터에 캐스트하는 안전한 방법

MyClass *mc1 = reinterpret_cast<MyClass*>(the_integer); 

그러나,이 문제의 주소가 실제로 MyClass의 객체를 보유하고 있는지 확인하기 위해 모든 런타임 검사를 수행하지 않습니다. 첫 번째 void (reinterpret_cast 사용)로 변환 한 다음 그 결과에 dynamic_cast를 사용하면 어떤 이점이 있는지 알고 싶습니다. 이와 같이 :

void *p = reinterpret_cast<void*>(the_integer); 
MyClass *mc1 = dynamic_cast<MyClass*>(p); 
assert(mc1 != NULL); 

두 번째 방법을 사용할 때 이점이 있습니까?

+4

두 번째 방법은 유효하지 않습니다. C++, dynamic_cast에 대한 식의 형식이 void *가 아닐 수도 있습니다. –

+2

정수 값이 원래 개체의 포인터 였다고 가정하면 int는 잠재적으로 포인터를 유지할 수 없습니다. 그래서 우리는 무효 *입니다. 유형이 지정되지 않은 경계를 넘어 전송을 위해 포인터를 캐스팅하는 경우 void *로 변환하고 원래 유형으로 되돌려 야합니다. –

+0

그는 'int'를 구체적으로 말하지 않았고 유형은 intptr_t 일 수 있습니다. –

답변

2

dynamic_cast에 대한 유형 검사는 다른 C++ 구현에 따라 다른 방식으로 구현됩니다. 특정 구현에 대한 대답을 원하면 사용중인 구현을 언급해야합니다. 이 질문에 일반적으로 대답하는 유일한 방법은 ISO 표준 C++을 참조하는 것입니다. 무효 포인터에 dynamic_cast를 호출 표준의 내 독서으로

는 불법입니다 :
dynamic_cast<T>(v) 

는 "T는 포인터 타입 인 경우, V 클래스 형을 완료하기 위해 포인터의를 rvalue한다"

(ISO C++ 표준 5.2.7.2 이상). void은 완전한 클래스 유형이 아니므로 표현식이 잘못되었습니다.

흥미롭게도, 유형, 즉이 경우

void * foo = dynamic_cast<void *>(some_pointer); 

dynamic_cast 항상 성공하고 결과 값이 가장 파생에 대한 포인터입니다,-가 무효 포인터가 될 수있다 주조되고 객체는 v을 가리 킵니다. void *int 나쁜 생각이다 "재 해석"모든

+1

'void * foo = dynamic_cast (some_pointer);'이후에'foo! = some_pointer' (일부 _pointer가 기본 하위 객체를 가리키고 있음을 의미)가 있기 때문입니다. –

2

아니요, 그렇게하는 데 특별한 이점이 없습니다. reinterpret_cast을 사용하는 순간 모든 배팅이 해제됩니다. 캐스트가 유효한지 여부는 전적으로 귀하에게 달려 있습니다.

2

실제로 심각한 이점이 없습니다. void *가 다형성 객체에 대한 포인터가 아닌 포인터를 가리키면 정의되지 않은 동작 (일반적으로 액세스 위반)이 즉시 발생합니다.

+2

그렇지 않을 경우를 제외하고. 정의되지 않은 동작에 의존하는 것은 결코 좋은 생각이 아닙니다. –

1

안전한 방법은 모든 라이브 MyClass 개체의 레코드를 유지하는 것입니다. 이 레코드를 std::set<void*>에 보관하는 것이 가장 좋습니다. 그러면 요소를 쉽게 추가, 제거 및 테스트 할 수 있습니다.

void* s로 저장하는 이유는 정수에서 정렬되지 않은 MyClass* 포인터를 만드는 것과 같은 불쾌감을 줄 우려가 없기 때문입니다.

0
  • 첫째. sizeof(int)이 4이고 sizeof(void *)이 8 (64x 시스템) 인 경우 잘못된 형식입니다.

  • dynamic_cast은 다형성 클래스의 경우에만 유효합니다.

0

당신이 알고있는 경우에 알려진 기본 클래스에 the_integer 점 (즉, 적어도 하나 명의 가상 멤버가), 사실 이점이있을 수 있는지에 대한 : 오브젝트가 특정 파생 클래스의 것을 알고. 그러나 먼저 기본 클래스에 reinterpret_cast에있는 다음 dynamic_cast 할 거라고 : dynamic_cast에서 void* 쓸모 단순히 잘못 사용

BaseClass* obj = reinterpret_cast<BaseClass*>(the_integer); 
MyClass* myObj = dynamic_cast<BaseClass*>(obj); 

합니다. dynamic_cast을 사용하여 메모리의 임의의 위치에 유효한 개체가 있는지 확인할 수 없습니다.

비 포인터 유형 변수에 주소를 저장할 때주의해야합니다. sizeof (void *)! = sizeof (int)와 같은 아키텍처가 있습니다. LP64.

0

옵션 1은 유일한 (반) 휴대용/유효한 옵션입니다.

옵션 2 : dynamic_cast와 같이 C++이 유효하지 않습니다 (void는 허용되지 않음).

구현 수준에서 대상 유형을 얻기 위해 소스 유형의 유형 정보가 필요합니다. void *에서 런타임 소스 유형 정보를 얻는 방법은 없습니다 (또는 방법이 없을 수도 있습니다). 따라서이 방법도 유효하지 않습니다.

Dynamic_Cast는 알 수없는 유형이 아닌 유형 계층을 위아래로 이동하는 데 사용됩니다.

형식이 지정되지 않은 포인터를 저장하려면 정수 대신 void *를 사용해야합니다. int를 포인터를 저장하기에 충분히 크지 않을 가능성이 있습니다.

0

C++에서 포인터를 처리하는 가장 안전한 방법은 typesafe를 처리하는 것입니다. 이는 :

  • 무효 포인터
  • 다른 프로세스에 대한 포인터를 전달 절대로
  • 당신이 스레드를 통해 포인터를 사용하려는 경우가
  • 가 weak_ptr를 고려하지 마십시오 포인터보다는 무엇에 포인터를 저장하지 않습니다

이유는 안전하지 않은 코드로 연결하지 않는 한 안전하지 않으며 피할 수 있습니다. 이 경우 MSalters의 답변을 고려해보십시오. 그러나 여전히 혼란 스럽습니다.

관련 문제