728x90

1. 들어가기
C++로 개발하다 보면 가장 자주 보는 캐스트가 static_cast다
그런데 막상 “언제 정확히 써야 하는지”를 설명해 보라고 하면
대충 “타입 맞을 때 쓰는 거” 정도로 흐리게 넘어갈 때가 많다
이 글에서는
- static_cast가 정확히 어떤 캐스트인지
- C 스타일 캐스트와 뭐가 다른지
- 실무 코드에서 자주 쓰는 패턴
을 정리해 본다
2. static_cast가 하는 일
한 줄로 요약하면
컴파일러가 타당하다고 판단할 수 있는 범위 안에서
타입 변환을 수행하는 캐스트
주로 이런 상황에서 사용된다
- 정수 ↔ 실수 변환
- int → double, double → int
- 상속 관계에서 업캐스트
- Derived* → Base*
- void* → 구체적인 포인터 타입
- enum ↔ 정수형 변환
static_cast는 논리적으로 말이 되는 변환만 허용한다고 보면 된다
3. 예제 숫자 타입 변환
int count = 7;
double avg = static_cast<double>(count) / 3.0;
굳이 static_cast를 안 써도 컴파일은 되지만
이렇게 써 두면
- 여기서 의도적으로 double로 바꾼다
- 정수 나누기가 아니라 실수 나누기를 하겠다는 의도다
라는 걸 코드만 보고도 바로 알 수 있다
4. 예제 상속 관계 업캐스트 / 다운캐스트
struct Animal {
virtual ~Animal() {}
virtual void Speak() = 0;
};
struct Dog : Animal {
void Speak() override { std::cout << "Woof\n"; }
void Shake() { std::cout << "Tail shaking\n"; }
};
void Sample()
{
Dog d;
// 업캐스트 암시적으로도 가능하지만
Animal* p1 = &d;
Animal* p2 = static_cast<Animal*>(&d); // 이렇게 명시도 가능
// 다운캐스트 실제 타입이 Dog라는 걸 확신하는 상황
Dog* pDog = static_cast<Dog*>(p1);
pDog->Shake();
}
여기서 업캐스트는 안전하다
Dog는 항상 Animal이기 때문이다
반대로 다운캐스트는
p1이 진짜 Dog를 가리킬 때만 안전하다
만약 Cat 타입 객체를 가리키고 있는데
static_cast<Dog*>를 해 버리면 동작이 정의되지 않는다
타입이 확실하지 않은 다운캐스트라면
static_cast 대신 dynamic_cast 를 고려하는 게 좋다
5. 언제 static_cast를 써야 할까 체크리스트
아래 질문에 “예”라고 답할 수 있다면 static_cast 후보라고 보면 된다
1 이 변환은 설계상 당연히 허용되는가
2 타입이 논리적으로 서로 호환되는가
- 예 숫자 ↔ 숫자, 업캐스트, void* → 원래 타입
3 런타임에 타입을 확인할 필요가 없는가
그렇지 않고
- 메모리 레이아웃까지 억지로 바꿔가며 캐스트해야 한다
→ reinterpret_cast 쪽에 더 가깝고 - 타입이 맞는지 런타임에 확인해야 한다
→ dynamic_cast 후보에 가깝다
6. 주의할 점
- 다운캐스트에 static_cast를 남발하면
나중에 타입이 바뀌었을 때
조용히 크래시나는 코드를 만들기 쉽다 - static_cast는 “안전해 보이지만
프로그램이 잘못된 전제를 가지고 있으면 그대로 따라간다”는 점을 기억해야 한다
7. 정리
- static_cast는 “타당한 범위 안에서의 타입 변환” 이라고 기억하면 편하다
- 숫자 계산이나 업캐스트, void*에서 원래 타입으로 돌아올 때 특히 자주 쓰인다
- 다운캐스트에도 쓸 수 있지만
이 경우에는 “정말 타입이 맞는지” 한 번 더 생각해 보는 습관이 필요하다
728x90
반응형
'Application > C++' 카테고리의 다른 글
| [C++] 캐스트 이해하기 (2) - reinterpret_cast (0) | 2025.12.09 |
|---|---|
| [C++] 숫자 쉼표(금액) 표시 하기 (Comma) (0) | 2023.11.08 |
| [C++] 2중 포인터 동적 할당 (0) | 2023.03.16 |
| [C++] enum 중복 값 쓰기 (0) | 2022.12.22 |
| [C++] 정렬 되는 연결 리스트(링크드 리스트) 만들기 (0) | 2022.12.15 |