문제

주소가 실제 포인터 유형으로 포함 된 적분 유형을 변환해야합니다. 다음과 같이 reinterpret_cast를 사용할 수 있습니다.

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

그러나 문제의 주소가 실제로 MyClass 객체를 보유하고 있는지 확인하기 위해 런타임 검사를 수행하지 않습니다. 먼저 void* (RenterPret_cast 사용)로 변환 할 때 이점이 있는지 알고 결과에서 Dynamic_cast를 사용하는지 알고 싶습니다. 이와 같이:

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

두 번째 방법을 사용하는 데있어 어떤 이점이 있습니까?

도움이 되었습니까?

해결책

체크인을 입력하십시오 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.

다른 팁

아니요, 그렇게 할 때 구체적인 이점이 없습니다. 당신이 사용하는 순간 reinterpret_cast, 모든 베팅은 꺼져 있습니다. 캐스트가 유효한지 확인하는 것은 당신에게 달려 있습니다.

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

안전한 방법은 모든 라이브 마이 클래스 개체의 기록을 유지하는 것입니다. 이 기록을 a로 유지하는 것이 가장 좋습니다 std::set<void*>, 이는 요소를 쉽게 추가, 제거 및 테스트 할 수 있음을 의미합니다.

그것들을 저장하는 이유 void*s는 정렬되지 않은 것을 만드는 것과 같은 불쾌한 위험을 감수하지 않는다는 것입니다. MyClass* 정수의 포인터.

  • 우선 "재 해석" int 에게 void * 나쁜 생각입니다. 만약에 sizeof(int) 4와 sizeof(void *) 8 (64x 시스템)은 잘못 형성되어 있습니다.

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

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

옵션 2 : Dynamic_cast (무효가 허용되지 않으므로)로 유효하지 않습니다.

구현 수준에서는 대상 유형에 도달하려면 소스 유형의 유형 정보가 필요합니다. 런타임 소스 유형 정보를 무효로부터 얻을 방법이 없거나 방법이 없으므로 유효하지 않습니다.

Dynamic_cast는 알려지지 않은 유형이 아닌 유형 계층을 위아래로 사용하는 데 사용됩니다.

참고로 정수가 아닌 void*를 사용하여 유형의 포인터를 저장해야합니다. int가 포인터를 저장하기에 충분히 크지 않을 가능성이 있습니다.

C ++에서 포인터를 처리하는 가장 안전한 방법은 TypeSafe를 처리하는 것입니다. 이것은 다음을 의미합니다.

  • 포인터를 포인터 이외의 다른 것에 보관하지 마십시오
  • 공허 포인터를 피하십시오
  • 다른 프로세스에 포인터를 전달하지 마십시오
  • 스레드 위에 포인터를 사용할 계획이라면 약 _ptr를 고려하십시오.

그 이유는 : 당신이 계획하고있는 일은 안전하지 않으며 안전하지 않은 (레거시?) 코드와 인터페이스하지 않는 한 피할 수 있습니다. 이 경우 MSALTERS의 답변을 고려하지만 여전히 번거 로움이라는 점에 유의하십시오.

확실히 알고 있다면 the_integer 알려진 기본 클래스 (적어도 하나의 가상 멤버가 있음)를 가리키면 실제로 이점이있을 수 있습니다. 개체가 특정 파생 클래스임을 아는 것이 좋습니다. 그러나 당신은해야합니다 reinterpret_cast 먼저 기본 클래스에 다음을 수행합니다 dynamic_cast:

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

사용 a void* 안에 dynamic_cast 쓸모없고 단순히 잘못되었습니다. 당신은 사용할 수 없습니다 dynamic_cast 메모리의 임의의 일부 위치에 유효한 개체가 있는지 확인하려면

비 포인터 유형 변수에 주소를 저장할 때도주의를 기울여야합니다. sizeof (void*)! = sizeof (int), 예를 들어 LP64의 아키텍처가 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top