C 타입 캐스팅과 유사하지만,
컴파일러가 캐스팅을 확인하기 때문에 컴파일 타임에 형변화에 대한 타입 오류를 잡아줌
사용법 :
static_cast<new type>(expression)
- new type으로 void형 가능
- 상속관계에 있는 포인터끼리는 변환이 가능함
(but, 부모 클래스 -> 자식 클래스로의 변환은 unsafe 하게 작동할 수 있음)
(dynamic_cast 를 통해 safe하게 변환 가능)
// c style
#include <iostream>
int main() {
char a = 'a';
int* p = (int*)&a;
*p = 5; // runtime error
return 0;
}
// cpp static_cast
#include <iostream>
int main() {
char a = 'a';
int* p = static_cast<int*>(&a); // 컴파일 에러
*p = 5;
return 0;
}
타입 변환에 대한 런타임 에러를 컴파일 타임에 잡아준다
#include <iostream>
class Parent {};
class Child : public Parent {};
class NotInheritance {};
int main() {
Parent* parent = new Parent();
Child* child = static_cast<Child*>(parent);
// 상속 관계에 포함되지 않으므로 컴파일 에러
NotInheritance* notInheritance = static_cast<NotInheritance*>(parent);
return 0;
}
상속관계의 포인터는 문제없음
static_cast와는 반대로 캐스팅이 유효한지 런타임에 검사하도록 함
만약, 캐스팅이 유효하지 않다면 null를 반환해줌
(=bad_cast에 대한 예외처리를 따로 해줘야 함)
사용법 :
dynamic_cast<new type>(expression)
부모 클래스 -> 자식 클래스로의 변환을 safe 하게 작동하게 해줌
#include <iostream>
class Parent {};
class Child : public Parent {};
class NotInheritance {
virtual void a() {}
};
int main() {
Child* child;
NotInheritance* notInheritance = new NotInheritance();
child = dynamic_cast<Child*>(notInheritance);
if (child == nullptr) {
std::cout << "캐스팅이 유효하지 않음" << std::endl;
}
return 0;
}
상속 관계에 있지 않은 형변환도 dynamic_cast에서는 동작하나 유효한 캐스팅이 아니기 때문에 null을 반환함.
NotInheritance
클래스에 virtual 함수가 추가된 이유는 C++ 에서 지원하는 RTTI 중 dynamic_cast 연산자를 사용하기 위해서이다.
강제로 형변환을 수행함 (예를 들어 정수형을 포인터형으로 변환 가능)
다만, 강제로 하기 때문에 예상치못한 런타임 에러가 발생할 순 있음
사용법 :
reinterpret<new type>(expression)
- const의 형변환은 수행할 수 없음.
#include <iostream>
class Parent {
public:
int a;
Parent() {
this->a = 2;
}
};
class Child : public Parent {
public:
void A() {
std::cout << "강제로 형변환 완료 후, A 함수 호출" << std::endl;
}
};
class NotInheritance {};
int main() {
Child* child;
NotInheritance* notInheritance = new NotInheritance();
child = reinterpret_cast<Child*>(notInheritance);
child->A(); // 형변환을 수행한 child의 A 함수는 호출이 가능함
std::cout << child->a; // 하지만 강제로 형변환을 했기 때문에 parent의 생성자가 호출되지 않음
return 0;
}
포인터에 const 속성을 부여하거나 제거할 때 사용
사용법 :
const_cast<new type>(expression)
#include <iostream>
int main() {
int value = 0;
const int* a = &value;
int* b = const_cast<int*>(a);
// 원래는 const int* -> int*의 변환은 컴파일 에러를 초래하지만 const_cast는 변환 가능
*b = 15;
std::cout << *a << std::endl;
std::cout << *b << std::endl;
}