C++에서의 캐스팅(형 변환)은 다른 언어와 마찬가지로 하나의 자료형을 다른 자료형으로 변환하는 것을 의미한다.
예를 들어 double형 변수를 int형 변수에 담는 아주 기초적인 예시가 있다.
C 언어에서의 형 변환은 아주 익숙한 코드들이 보일 것이다
int main()
{
int a = 3;
double b = 3.5414;
int c = b; // 묵시적 캐스트
int d = (int)b; // 명시적 캐스트
}
컴파일러가 알아서 형 변환을 해주는 묵시적 캐스트와 프로그래머가 변환할 자료형을 지정해주는 명시적 캐스트가 있다
다음의 C 스타일 캐스팅은 여전히 C++에서도 쓰이기는 하지만 C++에는 캐스팅 방법이 따로 있다.
static_castconst_castreinterpret_castdynamic_castbit_cast (C++20에서 부터 지원)C++에서 C 스타일의 캐스팅은 뒤에서 설명할 C++의 캐스트 방법 중 하나를 선택해 진행되는데 프로그래머 입장에서는 어떤 형 변환 방법이 선택되었는지 알 수 없어(컴파일러의 의도를 모름) 명백한 실수를 컴파일러가 캐치하지 못해 위험한 상황이 발생할 수 있다.
그러므로 C++ 개발자라면 C 스타일의 캐스팅을 되도록 쓰지 않고 안전하고 깔끔한 C++ 캐스팅을 사용하자!
정적 캐스트, 정적이라고 하면 언어에서 컴파일시에~ / 동적이라고 하면 런타임시에~를 의미한다
즉 static_cast 연산자를 통해 형변환을 하면 컴파일(정적) 타임에 형 변환이 가능한지(오류를 체크)를 검사한다
기본 자료형간의 형변환도 허용하며 포인터 타입의 형 변환은 허용하지 않지만 상속 관계에 있는 클래스 타입의 형 변환은 허용한다.
이때 상속 관계에서 static_cast를 사용할 때 주의할 점이 있다.
class Base
{
}
class Derived : public Base
{
}
업캐스팅은 자식 클래스의 참조나 포인터를 부모 클래스로 변환하는 것을 의미한다
int main()
{
Base* b;
Derived* d = new Derived();
b = static_cast<Base*>(d);
}
자식 클래스는 부모 클래스의 멤버 변수나 함수를 포함하기 때문에 업캐스팅은 항상 안전하며, 컴파일러가 변환을 암묵적으로 처리하기에 명시적으로 적어줄 필요가 없다
다운캐스팅은 부모 클래스의 참조나 포인터를 자식 클래스로 변환하는 것을 의미한다
int main()
{
Base* b = new Base();
Derived* d;
d = static_cast<Derived*>(b);
}
반대로 부모 클래스는 자식 클래스에 추가된 멤버 변수나 함수에 대한 정보가 없기 때문에 다운캐스팅은 안전하지 않으며, Crash가 날 수 있다.
그래서 다운캐스팅 시에는 뒤에서 볼 dynamic_cast를 사용한다.
static_cast는 형변환에 대한 타입체크를 런타임에 하지 않고 컴파일 타임에 정적으로 수행한다
static_cast는 일반적으로 다른 연산자들과 달리 기본 자료형의 형변환을 허용하므로 형 변환 연산자 중 가장 사용 빈도가 높다
그리고 다운캐스팅과 같은 오류를 체크 안하므로 성능은 더 좋을 수도 있다
이 형변환 연산자는 쉽게 말해 변수에 const 속성을 추가하거나 제거할 때 사용하는 연산자이다
void LibraryFunc(char* str);
void func(const char* str)
{
LibraryFunc(const_char<char*>(str));
}
어떠한 포인터 타입도 어떠한 포인터 타입으로 변환이 가능한 연산자
변환 관계에 놓인 두 개체의 관계가 명확하거나, 특정 목적을 달성할 때에만 사용하는 것이 바람직하다
런타임시에 형변환을 검사하여 형변환을 보다 안전하게 처리하는 연산자
class Base
{
public:
virtual ~Base() = default;
};
class Derived : public Base
{
public:
virtual ~Derived() = default;
};
int main()
{
// 올바른 사용 예시
Base* b;
Derived* d = new Derived();
b = d;
d = dynamic_cast<Derived*>(b);
}
C++20에서 추가된 연산자
위의 연산자들은 C++ 언어의 일부이지만 이 연산자는 표준 라이브러리의 일부이다
단순 복사 가능 타입이란 객체를 구성하는 내부 바이트를 char과 같은 타입의 배열처럼 비트 단위 복사로 쉽게 변환할 수 있는 타입