캐스팅(형변환, casting)
암시적 캐스팅
컴파일러가 형을 변환해준다.
형 변환이 허용될 때만 해준다.
명시적 캐스팅
프로그래머가 형 변환을 위한 코드를 직접 작성
C++ 의 캐스팅은 다음과 같다.
static_cast
const_cast
dynamic_cast
reinterpret_cast
C 스타일 캐스팅
아래 코드는 무엇을 할까? (자바에서도 다음과 같은 캐스팅 방법을 사용한다)
다음의 캐스팅 방법은 무슨 문제를 가지고 있을까?
C++ 에서 제공하는 캐스팅 중(4가지 캐스팅 방법) 하나를 하기 때문에, 명확하지 못하다...
명백한 실수일 때라도, 컴파일러가 캐치 하지 못한다.
C++ 캐스팅은 명시적으로 캐스팅 해 다음과 같은 문제를 해결했다. -> 하지만 하드웨어는 C, C++ 캐스팅을 구분하지 못한다.
정적캐스팅(static_cast)
1. 값
두 숫자형 값을 변환
값을 유지하려고 노력 (올림의 오차는 제외)
이진수 표기는 달라질 수 있다. -> float 를 int 로 변환했을 때, 소수점 아래는 버려지기 때문에, 이진수 표현이 다를 수 있다.
2. 개체 포인터
컴파일 시 상속 관계 확인 후 자식 클래스로 변환
런타임 시 실제 크래시가 날 수 있다. -> 컴파일 타임에는 상속 관계 만을 확인하는 것이기 때문에, 함수를 호출 가능한 것인지 까지는 확인하지 않는다.
재해석 캐스팅(reinterpret_cast)
-> 상당히 위험한 캐스팅이다!
전혀 연관없는 두 포인터의 형변환을 가능하게 해준다.
Cat* ↔️ House*
int* ↔️ char*
포인터와 포인터가 아닌 변수 사이의 형변환을 가능하게 해준다.
Cat* ↔️ unsigned int
하지만, 캐스팅 되더라도 이진수 표기는 달라지지 않는다! -> A 형의 이진수 표기를 B 형인 것처럼 해석한다는 것이다.(위험해보인다 .. 알아듣기도 힘들어 ..) -> 컴퓨터는 이진수의 값을 코드의 시점에서 해석하는 것이다! -> 개발자의 의도가 있을 것이라고 생각하고, 문법적으로 이상한 캐스팅이라더라도 허용해준다.
const_cast
const_cast 로는 형을 바꾸는 것이 아닌, const 를 제거할 때 사용한다.
포인터 형에서만 사용하는 것이 말이 된다. -> 값 복사는 원본의 영향을 주지 않기에 문제가 안된다!
const_cast 를 하고 있다면 무언가 단단히 잘못되는 것이다! -> 아래 함수를 살펴보면 함수 인터페이스에서 매개변수를 바꾸지 않겠다고 선언했는데! -> const 를 없애 매개변수의 값을 바꾼다? 말이 안된다!
외부 라이브러리를 사용할 때만 제한적으로 const_cast 를 사용하자 -> 내가 변경 권한이 없는 라이브러리를 사용할 때만! -> 외부 라이브러리의 인터페이스가 잘못 설계되어 있을 때!
동적캐스팅(dynamic_cast)
런타임에 캐스팅이 가능한지 판단을 하고 캐스팅이 가능할 때는 캐스팅, 아니라면 null 을 반환한다. -> 때문에, dynamic_cast 가 static_cast 보다 더 안전하다.
하지만, dynamic_cast 를 사용하기 위해서는 컴파일 중에 RTTI(실시간 타입정보, Real Time Type Infomation) 설정을 켜야한다! -> 이 기능을 키지 않는다면 static_cast 와 동일하게 작동한다.
대부분의 프로젝트에서는 RTTI 가 꺼져있다. -> 왜? C++ 을 쓰는 업계는 성능이 중요하다고 했는데, RTTI 를 버틸수 있을 만큼의 성능을 가지고 있지 않는다. -> 정말 좋은 개념이지만 실제로는 거의 쓰이지 않는다..
왜 이리, C++ 에는 문제가 많아..? 그럼 Best Practice 는 무엇이야?
기본적으로 static_cast 를 사용하자
코드에서 정말 필요할 때만 reinterpret_cast 를 사용하자
외부 라이브러리를 사용할 때만 제한적으로 const_cast 를 사용하자 -> 내가 변경 권한이 없는 라이브러리를 사용할 때만! -> 외부 라이브러리의 인터페이스가 잘못 설계되어 있을 때!
Last updated