static_cast, dynamic_cast, const_cast 및 reinterpret_cast가 언제 사용해야합니까?
질문
다음의 적절한 용도는 무엇입니까?
static_cast
dynamic_cast
const_cast
reinterpret_cast
- C-style cast
(type)value
- Function-style cast
type(value)
특정 사례에서 어떤 사용을 위해 사용할 것인가?
답변
static_cast는 처음 사용하려고 시도해야합니다.유형 (예 : int to float 또는 void to pointer) 간의 암시 적 변환과 같은 것들이 있으며 명시 적 변환 함수 (또는 암시 적들)를 호출 할 수도 있습니다.명시 적으로 static_cast를 명시 적으로 진술하는 경우에는 t (무언가) 구문이 (t) 뭔가와 같아지고 피해야한다는 점에 유의해야합니다.그러나 (무언가, 뭔가 뭔가)는 안전하지만 생성자를 호출하는 것이 보장됩니다.
static_cast는 상속 계층 구조를 통해 캐스팅 할 수도 있습니다.위쪽으로 캐스팅 할 때 (기본 클래스쪽으로) 가상 상속을 통해 던지지 않는 한 가상 상속을 통해 사용할 수있는 한 사용할 수 있습니다.그러나 실제로 객체의 유형이 아닌 형식이 아닌 유형의 계층 구조 아래로 static_cast를 검사하지는 않습니다.
const_cast를 사용하여 변수를 제거하거나 추가 할 수 있습니다.다른 C ++ 캐스트는 제거 할 수 있습니다 (REInterPret_cast조차도).원래 변수가 const가되면 이전의 const 값을 수정하는 것이 정의되지 않는다는 점에 유의해야합니다.const를 사용하여 선언되지 않은 무언가에 대한 참조를 사용하여 const를 사용하면 안전합니다.이는 멤버 함수를 오버로드하는 경우에 멤버 함수를 오버로드 할 때 유용 할 수 있습니다.또한 멤버 함수 과부하를 호출하는 것과 같이 오브젝트에 const가 첨가하는 데 사용할 수도 있습니다.
const_cast는 또한 휘발성과 유사하게 작동하지만 덜 일반적입니다.
Dynamic_cast는 다형성을 취급하는 데 독점적으로 사용됩니다.다형성 유형에 대한 포인터 또는 참조를 다른 클래스 유형으로 주조 할 수 있습니다 (다형성 유형에는 적어도 하나의 가상 함수, 선언 또는 상속).단지 아래쪽으로 주조하는 것 이상으로 사용할 수 있습니다 - 옆으로 또는 심지어 다른 체인을 던질 수 있습니다.dynamic_cast는 가능한 경우 원하는 객체를 찾고 반환합니다.할 수없는 경우 포인터의 경우 nullPtr을 반환하거나 참조의 경우에 STD :: BAD_CAST를 던지게됩니다.
Dynamic_cast에는 몇 가지 제한 사항이 있습니다.상속 계층 구조 (소위 '두려운 다이아몬드')에 동일한 유형의 여러 개체가있는 경우 작동하지 않습니다. 가상 상속을 사용하지 않습니다.또한 대중의 상속을 통과 할 수 있습니다. 항상 보호 또는 개인 상속을 통해 여행하지 못합니다.그러나 이러한 형태의 상속은 드물기 때문에 이것은 거의 문제가되지 않습니다.
ReinterPret_cast는 가장 위험한 캐스트이며 매우 드물게 사용해야합니다.하나의 포인터에서 다른 포인터로 가치를 캐스팅하거나 int 또는 모든 종류의 다른 불쾌한 것들을 저장하는 것과 같이 다른 유형으로 직접 다른 유형으로 바뀝니다.크게 REINTERPRET_CAST와 함께 얻을 수있는 유일한 보증은 일반적으로 결과를 원래 유형으로 되돌아 가면 똑같은 값을 가져옵니다 (중간 유형이 원래 유형보다 작지 않은 경우).REInterPret_cast가 할 수없는 여러 변환이 있습니다.주로 원시 데이터 스트림을 실제 데이터로 바꾸거나 포인터의 낮은 비트에 데이터를 정렬 된 데이터에 저장하는 것과 같은 특히 이상한 변환 및 비트 조작을 위해 사용됩니다.
C 스타일의 캐스트 및 기능 스타일 캐스트는 (유형) 객체 또는 유형 (객체)을 각각 사용하고 기능적으로 동등합니다.그들은 다음 중 첫 번째로 정의됩니다.
const_cast. static_cast (액세스 제한을 무시하지만) static_cast (위 참조), const_cast. ReinterPret_cast. REInterPret_cast, 다음 const_cast.
그러므로 어떤 경우에는 다른 캐스팅을 대체 할 수 있지만, Static_cast가 성공하거나 STATIC_CAST가 성공하지 않는 한, 명시 적 캐스팅이 필요하지 않은 경우에, 명시 적 캐스팅이 필요할 때 극도로 위험 할 수 있으므로 매우 위험 할 수 있습니다.ReinterPret_cast가 실패합니다.그런 다음 더 오래 명시 적 옵션을 더 이상 고려하십시오.
또한 C 스타일 캐스팅은 또한 static_cast를 수행 할 때 액세스 제어를 무시할 때 다른 캐스팅이없는 작업을 수행 할 수있는 기능을 가지고 있음을 의미합니다.이것은 대부분 Kludge이지만, 내 마음 속에는 C 스타일의 캐스트를 피할 수있는 또 다른 이유 일뿐입니다.
답변
상속 계층에서 포인터 / 참조를 변환하기 위해 DYNAMIC_CAST를 사용하십시오. 일반 유형 변환을 위해 static_cast를 사용하십시오. 비트 패턴의 로우 레벨 재 해석을 위해 REINTERPRET_CAST를 사용하십시오.극심한주의를 기울여서 사용하십시오. const_cast를 사용하여 const / volatile을 빼냅니다.const-purect dect api를 사용하여 멈추지 않으면 이것을 피하십시오.
답변
(이론적이고 개념적 설명이 많이 주어졌습니다)
아래는 static_cast, dynamic_cast, const_cast, reinterpret_cast를 사용했을 때 다음의 일부입니다.
(또한 이는 이것이 설명을 이해합니다. http://www.cplusplus.com/doc/tutorial/typecasting/)
static_cast :
OnEventData(void* pData)
{
......
// pData is a void* pData,
// EventData is a structure e.g.
// typedef struct _EventData {
// std::string id;
// std:: string remote_id;
// } EventData;
// On Some Situation a void pointer *pData
// has been static_casted as
// EventData* pointer
EventData *evtdata = static_cast<EventData*>(pData);
.....
}
dynamic_cast :
void DebugLog::OnMessage(Message *msg)
{
static DebugMsgData *debug;
static XYZMsgData *xyz;
if(debug = dynamic_cast<DebugMsgData*>(msg->pdata)){
// debug message
}
else if(xyz = dynamic_cast<XYZMsgData*>(msg->pdata)){
// xyz message
}
else/* if( ... )*/{
// ...
}
}
const_cast :
// *Passwd declared as a const
const unsigned char *Passwd
// on some situation it require to remove its constness
const_cast<unsigned char*>(Passwd)
REInterPret_cast :
typedef unsigned short uint16;
// Read Bytes returns that 2 bytes got read.
bool ByteBuffer::ReadUInt16(uint16& val) {
return ReadBytes(reinterpret_cast<char*>(&val), 2);
}
답변
내부의 조금을 거의 알지 못한다면 도움이 될 수 있습니다 ...
static_cast.
C ++ 컴파일러는 이미 플로트와 같은 스케일러 유형을 int로 변환하는 방법을 이미 알고 있습니다.그 (것)들을 위해 static_cast를 사용하십시오. Compiler가 Type A에서 B에서 B로 변환하도록 요청하면 static_cast는 a param으로 전달 된 b의 생성자를 호출합니다.대안으로, A는 변환 연산자 (즉, A :: 연산자 B ())를 가질 수있다.B에 이러한 생성자가 없거나 변환 연산자가없는 경우 컴파일 시간 오류가 발생합니다. A *에서 B까지 캐스팅하는 것은 A와 B가 상속 계층 (또는 void)에있는 경우 항상 성공합니다. 그렇지 않으면 컴파일 오류가 발생합니다. Gotcha : 기본 포인터를 파생 된 포인터에 캐스팅하지만 실제 개체가 실제로 유래 된 유형이 아니면 오류가 발생하지 않습니다.당신은 나쁜 포인터를 얻고 런타임에 segfault가 매우 가능성이 높습니다.& ~ b &. Gotcha :베이스 또는 Victersa로 파생 된 출신의 캐스트 새 사본을 만듭니다!C # / Java에서 오는 사람들을 위해 결과가 기본적으로 파생 된에서 생성 된 잘게 잘린 오프 객체이기 때문에 이것은 거대한 놀람 일 수 있습니다.
Dynamic_cast.
Dynamic_cast는 런타임 유형 정보를 사용하여 캐스트가 유효한지 파악합니다.예를 들어, 포인터가 실제로 파생 된 유형이 아닌 경우 (base *) to (파생 *)가 실패 할 수 있습니다. 이것은, DANANCH_CAST는 static_cast와 비교하여 매우 비쌉니다! * to b *의 경우 캐스트가 유효하지 않은 경우 Dynamic_cast는 NullPtr을 반환합니다. A & to B & 캐스팅이 유효하지 않은 경우 Dynamic_cast는 BAD_CAST 예외를 throw합니다. 다른 캐스팅과 달리 런타임 오버 헤드가 있습니다.
const_cast.
static_cast는 const가 아닌 다른 방식을 할 수는 있지만 다른 방법으로 이동할 수 없습니다.const_cast는 두 가지 방법을 모두 수행 할 수 있습니다. 이것이 오는 한 가지 예제가 쉽게 오는 것과 같은 일부의 컨테이너를 반복하고있는 것과 같은 일부 컨테이너를 통해 요소를 변경하지 않도록하십시오.그러나 귀하의 의도가 객체의 키가 아닌 멤버를 수정하는 것이 좋습니다.const_cast를 사용하여 constness를 제거 할 수 있습니다. 또 다른 예는 T & SOMECLASS :: FOO ()뿐만 아니라 CONST T & SOMECLASS :: FOO () COND를 구현하려는 경우가 있습니다.코드 복제를 방지하려면 Const_CAST를 다른 기능의 한 함수의 반환 값에 적용 할 수 있습니다.
ReinterPret_cast.
이것은 기본적 으로이 메모리 위치에서 이러한 바이트를 가져 와서 주어진 객체로 생각합니다. 예를 들어, Float의 비트가 어떻게 보이는지 확인하려면 4 바이트의 int의 4 바이트를 4 바이트로로드 할 수 있습니다. 분명히 데이터가 유형에 맞지 않으면 SegFault를 얻을 수 있습니다. 이 캐스트에 대한 런타임 오버 헤드가 없습니다.
답변
이 질문에 대답합니까?
나는 ReinterPret_cast를 사용한 적이 없으며, 필요로하는 경우에 달리기를 궁금해하는 것은 나쁜 디자인의 냄새가 아닙니다.코드 기반에서는 DYNAMIC_CAST에서 작동합니다.static_cast와의 차이점은 dynamic_cast가 런타임 검사를 수행 할 수있는 런타임 검사 (더 안전한) 또는 (보다 오버 헤드)가 원하는 것 (MSDN 참조)입니다.
답변
지금까지 다른 답변 이외에, 여기서는 static_cast가 충분하지 않아서 reinterPret_cast가 필요하다는 것을 알지 못한 예가 있습니다.출력 매개 변수에 다른 클래스의 오브젝트에 대한 포인터가 반환되는 함수가 있다고 가정하십시오 (공통 기본 클래스를 공유하지 않는).그러한 함수의 실제 예는 CoCreateInstance () (실제로 void **)의 마지막 매개 변수를 참조하십시오.이 기능에서 특정 클래스 클래스를 요청하므로 포인터의 유형 (종종 COM 개체를 위해 수행)을 미리 알고 있습니다.이 경우 STATIC_CAST가있는 void **를 void **로 캐스팅 할 수 없습니다. REInterPret_cast
코드에서 :
#include <windows.h>
#include <netfw.h>
.....
INetFwPolicy2* pNetFwPolicy2 = nullptr;
HRESULT hr = CoCreateInstance(__uuidof(NetFwPolicy2), nullptr,
CLSCTX_INPROC_SERVER, __uuidof(INetFwPolicy2),
//static_cast<void**>(&pNetFwPolicy2) would give a compile error
reinterpret_cast<void**>(&pNetFwPolicy2) );
그러나 static_cast는 간단한 포인터 (포인터에 대한 포인터가 아님)에서 작동하므로 다음과 같은 방식으로 REInterPret_cast (추가 변수 가격)를 피하기 위해 위의 코드를 다시 작성할 수 있습니다.
#include <windows.h>
#include <netfw.h>
.....
INetFwPolicy2* pNetFwPolicy2 = nullptr;
void* tmp = nullptr;
HRESULT hr = CoCreateInstance(__uuidof(NetFwPolicy2), nullptr,
CLSCTX_INPROC_SERVER, __uuidof(INetFwPolicy2),
&tmp );
pNetFwPolicy2 = static_cast<INetFwPolicy2*>(tmp);
출처:https://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used
최근댓글