📒 C++ - cast
📌 static_cast
- 논리에 맞는 명시적 형변환을 수행한다.
- 컴파일 시점에 체크하기 때문에 안전하다.
📌 dynamic_cast
- 같은 상속 계층에 속한 타입끼리 캐스팅할 때 사용한다.
- 런타임 시점에 체크한다.
- 캐스팅이 적합하지 않으면 nullptr을 반환한다.
📌 const_cast
- const 속성을 컨트롤할 때 사용한다.
- 사용할 상황을 만드는 것을 피하고, 사용을 지양해야 한다.
- 그러나 아래의 예제 같은 경우에는 예외적으로 안전하게 사용될 수 있는 경우를 보여준다.
#pragma warning(disable: 4996)
#include <cstring>
#include <iostream>
using namespace std;
class String
{
private:
char* _chars;
public:
String(const char* chars)
: _chars(new char[strlen(chars) + 1])
{
strcpy(_chars, chars);
}
char& operator[](int index)
{
return _chars[index];
}
const char& operator[](int index) const
{
return _chars[index];
}
};
int main()
{
String s0("abc");
cout << s0[0] << endl;
s0[0] = 'b';
const String& s1 = s0;
cout << s1[0] << endl;
}
- 위를 보면 operator[] 함수가 두 번 정의되어 있어야 하는 상황이다.
- 매번 const 여부에 따라 항상 중복 코드를 만들어야 하는 이슈가 생긴다.
- 위처럼 코드가 짧으면 괜찮을 수 있지만, 만약 코드가 매우 길다면 번거로운 일이 아닐 수 없다.
- 이것을 const_cast를 사용하면 해결할 수 있다.
#pragma warning(disable: 4996)
#include <cstring>
#include <iostream>
using namespace std;
class String
{
private:
char* _chars;
public:
String(const char* chars)
: _chars(new char[strlen(chars) + 1])
{
strcpy(_chars, chars);
}
char& operator[](int index)
{
const String& s = *this;
const char& c = s[index];
return const_cast<char&>(c);
}
const char& operator[](int index) const
{
return _chars[index];
}
};
int main()
{
String s0("abc");
cout << s0[0] << endl;
s0[0] = 'b';
const String& s1 = s0;
cout << s1[0] << endl;
}
- char& operator[](int index)를 보면 *this를 상수화한 후, const_cast<char&>로 캐스팅하여 리턴하였다.
- 위 코드가 안전한 이유는 애초에 *this는 상수가 아니었고, *this를 가리키는 레퍼런스에만 상수화하였기 때문에 안전하다.
- 웬만하면 사용할 일을 만들지 않는 것이 좋다.
📌 reinterpret_cast
- 지정한 자료형으로 비트를 재해석한다.
- undefined behavior을 많이 유발하기 때문에 사용할 때 주의해야 한다.
- 이식성을 떨어트리는 주요 원인이다.
#include <iostream>
using namespace std;
int main()
{
int i = 1;
float* a = reinterpret_cast<float*>(&i);
cout << *a << endl;
cout << FLT_TRUE_MIN << endl;
float b = i;
cout << b << endl;
}
Output:
1.4013e-45
1.4013e-45
1