[C++] 형변환(Casting)
카테고리: Cpp
태그: Inheritance Casting
이 글은 C++ 형변환(Casting)을 공부하고 정리한 글입니다
형변환
- 자료형을 다른 형태로 변경하는 것
-
컴파일러가 자동으로 변환해주는 암시적 형변환과 프로그래머가 직접 해당 자료형을 명시하는 명시적 형변환이 있다
static_cast
int number1 = 3; short number2 = static_cast<int>(number1); Animal* myPet = new Cat(2, "CoCo"); Cat* myCat = static_cast<Cat*>(myPet); // OK Dog* myDog = static_cast<Dog*>(myPet); // 컴파일은 된다. 그러나 위험하다 // static_cast는 Animal이라는 클래스를 Dog라는 클래스가 상속 받았는지만 체크하기때문에 컴파일이 된다 // 하지만 Cat 클래스가 Dog 클래스의 멤버를 가지고 있지 않기때문에 비정상적인 결과를 초래할 수 있다
- 컴파일시에 형변환을 해준다
- 값일 경우
- 두 숫자 형 간의 변환
- 값을 유지 (단, 반올림 오차는 제외)
- 이진수 표기는 달라질 수 있음
- 두 숫자 형 간의 변환
- 개체 포인터일 경우
- 변수형 체크 후 베이스 클래스를 파생 클래스로 변환
- 컴파일 시에만 형 체크 가능
- 실행 도중 여전히 크래시가 날 수 있음
reinterpret_cast
int* signedNumber = new int(-10); unsigned int* unsignedNumber = reinterpret_cast<unsinged int*>(signedNumber);
- 연관 없는 두 포인터 형 사이의 변환을 허용
- Cat* <-> House*
- char* <-> int*
- 포인터와 포인터가 아닌 변수 사이의 형 변환을 허용
- Cat* <-> usinged int
- 이진수 표기는 달라지지 않음
- A형의 이진수 표기를 그냥 B형인 것처럼 해석
const_cast
Animal* myPet = new Cat(2, "Coco"); const Animal* petPtr = myPet; Animal* myAnimal2 = const_cast<Animal*>(petPtr); // OK Cat* myCat2 = const_cast<Cat*>(petPtr); // 컴파일 에러
- const 또는 volatile 애트리뷰트를 제거할 때 사용
- const_cast로 형을 바꿀 수 없음
- const_cast를 코드에서 쓰려고 한다면 무언가 잘못쓰고 있을 가능성이 높다
- [써드파티 라이브러리가 const를 제대로 사용하지 않을 때] 정도만 사용하자
dynamic_cast
Animal* myPet = new Cat(); Dog* myDog = dynamic_cast<Dog*>(myPet); // 컴파일은 된다. 하지만 널값을 반환해준다 if (myDog != NULL) { ... }
- 실행 중에 형을 판단
- 호환되지 않는 자식형으로 캐스팅하려 하면 NULL을 반환
- 따라서, dynamic_cast가 static_cast보다 안전
- 만약 사용하려면 RTTI(실시간 타입정보, Real-Time Type Information)를 켜야 함
- 만약 RTTI를 키지 않는다면 dynamic_cast와 static_cast는 동일하게 동작
캐스팅 규칙
- 기본적으로 static_cast를 쓸 것
- reinterpret_cast<Cat> 대신 static_cast<Cat>
- 만약 Cat이 Animal이 아니라면 컴파일러가 에러를 뱉음
- reinterpret_cast<Cat> 대신 static_cast<Cat>
- reinterpret_cast를 쓸 것
- 포인터와 비포인터 사이의 변환
- 서로 연관이 없는 포인터 사이의 변환은 그 데이터형이 맞다고 정말 확인할 때만 할 것
- 내가 변경권한이 없는 외부 라이브러리를 호출할 때만 const_cast를 쓸 것
참조
💻 열심히 공부해서 작성 중이니 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 알려주시면 감사하겠습니다! 😸
댓글 남기기