[열혈 C++] Chap16: 형 변환
형 변환
✏️dynamic_cast
-
상속관계에서의 안전한 형 변환
-
dynamic_cast<T>(expr)
- < > 사이엔 변환하고자 하는 자료형 이름을 두지만, 객체 포인터 또는 참조형이 와야한다.
- ( ) 사이엔 변환의 대상이 와야한다
-
유도클래스의 포인터/참조형 데이터를 기초클래스의 포인터/참조형 데이터로 형 변환 하는 경우
#include <iostream> using namespace std; class Car { private: int fuelGauge; public: Car(int fuel) : fuelGauge(fuel) { } void ShowCarState() { cout<<"잔여 연료량: "<<fuelGauge<<endl; } }; class Truck : public Car { private: int freightWeight; public: Truck(int fuel, int weight) : Car(fuel), freightWeight(weight) { } void ShowTruckState() { ShowCarState(); cout<<"화물의 무게: "<<freightWeight<<endl; } }; int main(void) { Car * pcar1=new Truck(80, 200); Truck * ptruck1=dynamic_cast<Truck*>(pcar1); // 컴파일 에러 Car * pcar2=new Car(120); Truck * ptruck2=dynamic_cast<Truck*>(pcar2); // 컴파일 에러 Truck * ptruck3=new Truck(70, 150); Car * pcar3=dynamic_cast<Car*>(ptruck3); // 컴파일 OK! return 0; }
- 다이나믹캐스트는 유도클래스 데이터를 기초클래스 데이터로 형변환 하겠다는 의미가 담겨있기 때문에, 기초클래스형 포인터 변수를 유도클래스형으로 바꾸려는 것과, 기초클래스 데이터를 유도클래스 데이터로 바꾸는 것은 모두 컴파일 에러가 난다.
✏️static_cast
- A 타입에서 B 타입으로
static_cast<T>(expr)
- 이 친구는 기초 클래스를 유토 클래스 포인터 및 참조형으로 조건없이 형 변환 시켜주는 아이다.
- 그러나 책임은 프로그래머가 져야하므로 안정성이 떨어진다.
Car * pcar1=new Truck(80, 200); Truck * ptruck1=static_cast<Truck*>(pcar1); Car * pcar2=new Car(120); Truck * ptruck2=static_cast<Truck*>(pcar2); //이런 댕짓을 해준다 그러나 굳이 이렇게 코드를 짤 이유가 있나 //안정성은 떨어지고 책임도 컴파일러가 지지 않는다. 원하는 결과가 안나올 수 있다
- 상속관계 형 변환 뿐만아니라 기본 자료형 변환도 해준다.
double res = static_cast<double>(20)/3;
요런식으로.
✏️const_cast
- const 성향을 제거하는 형 변환
const_cast<T>(expr)
- const로 선언된 참조자, 포인터의 const 성향을 제거
#include <iostream> using namespace std; void ShowString(char* str) { cout<<str<<endl; } void ShowAddResult(int& n1, int& n2) { cout<<n1+n2<<endl; } int main(void) { const char * name="Lee Sung Ju"; ShowString(const_cast<char*>(name)); const int& num1=100; const int& num2=200; ShowAddResult(const_cast<int&>(num1), const_cast<int&>(num2)); return 0; } /*결과 Lee Sung Ju 300 */
✏️reinterpret_cast
- 상관없는 자료형으로 형 변환
reinterpret_cast<T>(expr)
- 예시
#include <iostream> using namespace std; int main(void) { int num=0x010203; char * ptr=reinterpret_cast<char*>(&num); for(int i=0; i<sizeof(num); i++) cout<<static_cast<int>(*(ptr+i))<<endl; return 0; } /*결과 3 2 1 0 */
- 포인터를 대상으로 하는, 그리고 포인터와 관련이 있는 모든 유형의 형 변환을 허용한다