답변:
사용static_cast
: 여기에서 어떤 변환이 이루어 졌는지 정확하게 설명하는 가장 좁은 캐스트입니다.
reinterpret_cast
"타입 안전성을 완전히 무시하고 A에서 B로 캐스트"한다는 의미이므로 사용 하는 것이 더 적합 하다는 오해 가 있습니다.
그러나 이것은 실제로의 효과를 설명하지는 않습니다 reinterpret_cast
. 그보다 reinterpret_cast
는 여러 가지 의미를 지니고 있으며, 그 의미는 모두 "에 의해 수행되는 매핑 reinterpret_cast
이 구현 정의되어있다"는 것입니다. [5.2.10.3]
그러나에서 주조의 특정 경우 void*
에 T*
매핑 완전히 표준에 의해 잘 정의입니다; 즉, 주소를 변경하지 않고 유형이없는 포인터에 유형을 지정합니다.
이것이 선호하는 이유 static_cast
입니다.
또한, 더 중요한 것은 모든 사용이 reinterpret_cast
실제로 (포인터를 위해) 다른 것으로 변환하기 때문에 매우 위험 하다는 사실 이며, static_cast
훨씬 더 제한적이므로 더 나은 보호 수준을 제공합니다. 이것은 실수로 한 포인터 유형을 다른 포인터 유형으로 강제 변환하려고했던 버그에서 이미 나를 구해 냈습니다.
이것은 어려운 질문입니다. 한편, Konrad는 reinterpret_cast 의 스펙 정의에 대해 훌륭한 지적을하고 있지만 실제로는 아마 같은 일을합니다. 반면, 포인터 유형 사이를 캐스팅하는 경우 (예를 들어 char *를 통해 메모리에서 인덱싱 할 때 일반적으로 발생하는 것처럼) static_cast 는 컴파일러 오류를 생성하고 어쨌든 reinterpret_cast 를 사용해야 합니다.
실제로 는 캐스트 작업의 의도를 더 설명하기 때문에 reinterpret_cast를 사용 합니다. 다른 연산자가 포인터 재 해석만을 지정하는 경우를 확실히 만들 수는 있지만 동일한 주소가 반환되도록 보장하지만 표준에는 없습니다.
reinterpret_cast
!
항상 가장 약한 캐스트를 사용하는 것이 좋습니다.
reinterpret_cast
에 대한 포인터를 캐스팅하는 데 사용될 수 있습니다 float
. 캐스트의 구조가 깨질수록 더 많은주의가 필요합니다.
의 경우 char*
c 스타일 캐스트를 사용 reinterpret_pointer_cast
합니다.
float f = *reinterpret_cast<const float*>(&p);
float
, 이는 거짓입니다. 표현 캐스트 void **
에 const float *
다음과 변환, 참조 취소 조작을 (캐스트가되지 않는) 사용 const float *
에 float
.
내 개인적인 취향은 다음과 같은 코드 활용 능력을 기반으로합니다.
void* data = something;
MyClass* foo = reinterpret_cast<MyClass*>(data);
foo->bar();
또는
typedef void* hMyClass; //typedef as a handle or reference
hMyClass = something;
const MyClass& foo = static_cast<MyClass&>(*hMyClass);
foo.bar();
둘 다 결국 동일하지만 static_cast는 미들웨어, 앱 환경에서 더 적합 해 보이지만, 캐스트 재 해석은 하위 수준 라이브러리 IMHO에서 볼 수있는 것과 비슷합니다.