static_cast는 C++에서 가장 일반적으로 사용되는 형 변환 연산자로, 평범하고 일상적인 타입 변환을 수행합니다. 컴파일러가 암시적으로 처리하는 타입 강제 변환(implicit type coercion)과 동일한 방식으로 작동하며, 필요할 때 프로그래머가 명시적으로 호출할 수도 있습니다. 대표적인 활용 사례로는 float를 int로 변환하거나 char를 int로 변환하는 경우가 있으며, 상속 관계에 있는 클래스 포인터 간의 변환에도 사용할 수 있습니다.
static_cast 기본 사용법
다음은 float 타입 변수를 int 타입으로 변환하는 예제입니다.
#include <iostream>
using namespace std;
int main() {
float x = 4.26;
int y = x; // C 스타일 캐스트 (암시적 변환)
int z = static_cast<int>(x); // static_cast를 이용한 명시적 변환
cout << "형 변환 후 값: " << z;
return 0;
}
실행 결과
형 변환 후 값: 4
float에서 int로 변환될 때 소수점 이하 자릿수는 버려지고 정수 부분만 남습니다. 위 예제에서 4.26이 4로 변환된 것을 확인할 수 있습니다.
관련 없는 타입 간 변환 시 발생하는 오류
static_cast는 서로 관련이 있는 타입 간의 변환만 허용합니다. 만약 상속 관계 등 어떤 연관성도 없는 클래스끼리 포인터를 변환하려고 하면 컴파일 오류가 발생합니다.
예제
#include<iostream>
using namespace std;
class Base {};
class Derived : public Base {};
class MyClass {};
int main(){
Derived* d = new Derived;
Base* b = static_cast<Base*>(d); // 상속 관계가 있으므로 정상 동작
MyClass* x = static_cast<MyClass*>(d); // 관련 없는 타입이라 컴파일 오류 발생
return 0;
}
출력 결과
[Error] invalid static_cast from type 'Derived*' to type 'MyClass*'
위 예제에서 Derived*에서 Base*로의 변환은 두 클래스가 상속 관계에 있기 때문에 문제없이 수행됩니다. 반면 MyClass는 Derived와 아무런 관련이 없으므로 static_cast를 적용할 수 없으며, 컴파일 단계에서 오류가 발생합니다.
static_cast 사용 시 알아두면 좋은 점
- static_cast는 컴파일 타임에 타입 검사를 수행하므로 런타임 오버헤드가 거의 없습니다.
- 상속 관계에서 다운캐스트(부모 → 자식)에도 사용할 수 있지만 타입 안전성이 보장되지 않으므로, 런타임 타입 검사가 필요한 경우에는 dynamic_cast를 사용하는 것이 좋습니다.
- C 스타일 캐스트보다 변환 의도가 명확하게 드러나기 때문에, 현대 C++ 코드에서는 static_cast 사용을 권장합니다.