Language/C++

C++ :: C++ Style Cast (C++ 스타일 캐스트)

VallistA2015. 4. 2. 01:27

C언어와 다르게 C++에서도 좀 더 명확한 방향으로 캐스트 스타일이 바뀌게 되었다.

우리는 기존 C에서 강제형변환을 통한 캐스트 스타일을 바꾸어주었는데 이는 실질적으로 연산 과정에 부하를 주었다.


C# 에서는 박싱과 언박싱으로 표현하고 있는데, 이는 상당히 연산 과정을 느리게 한다.

블로그에 박싱과 언박싱 관련해서 글을 쓴 것이있다. 참조하면 괜찮을듯 싶다.


이번 글에서는 C++ Style Casting 을 다뤄보고자 한다.


먼저 사용방법은 이와 같다. (모두 공통적임)



그리고 C++ 캐스팅에서는 형변환이 가능한 경우와 불가능한 경우가 존재한다. 


1. 실수형 <-> 정수형 변환 

2. 포인터 끼리 형변환은 상속관계있는 포인터만 가능

3. 상호 호환되는 열거형과 정수형과의 변환이 가능하다. 

4. double과 float의 소수를 커트해내는 형변환도 가능

5. 타입이 다른 포인터의 형 변환 불가 (void* 로 가능하게 만들기 가능)


여기서 2번의 경우에는 좀 희귀한 경우인데 이와같은 경우에는 캐스팅 방법이 있다.


1. Up Casting (업 캐스팅)

 - 자식 클래스의 객체를 부모 클래스의 포인터로 형 변환 할 때

 - 안정성 보장

 - 형 변환을 통한 대입을 안해도 됨.


2. Down Casting (다운 캐스팅)

 - 부모 클래스의 객체를 자식 클래스로 형 변환 하는 것을 말함.

 - 안정성 보장 불가

 - 형변환 안하면 대입 불가능


다음은 여러가지 캐스팅 연산자에 대해서 알아보겠다.



const_cast 


const와 volatile, _unaligned type으로 선언한 변수들의 각 특성을 제거하는데 쓰임.

대표적으로는 const 붙지않은 함수에 대입할 때 const_cast 써서 넣어줌


1. 포인터의 상수성 변경하고 싶을 때 사용

2. 상수성 제거하는 것 외의 타입 변환 허용 X

3. 상수 지시 포인터를 비 상수 지시 포인터로 비 상수 포인터를 상수 지시 포인터로 변환 할 때도 사용.

   비 상수 지시 포인터는 항상 상수 지시 포인터로 변환 가능해서 캐스트 연산자 굳이 쓸 필요 없음. (안쓰는게 남 연산과정도 줄어듬)


예제 소스 : 


결과 :



주로 사용하는 때는 외부 라이브러리의 const 붙은 인자에 넣어줄때 사용용도라던지에 요긴하게 쓰인다.


dynamic_cast


dynamic_cast는 상속 관계 안에서 포인터나 참조자의 타입을 기본 클래스에서 파생 클래스로의 다운 캐스팅과 다중 상속에서 기본 클래스 간의 안전한 타입 캐스팅에 사용됨.

안전한 타입 캐스팅은 런타임에 타입 검사를 하는거며 (쓰레드 X)

const_cast와 같이 다른 용도로는 사용하지 못하고 용도가 명확함.


제약 사항


1. 상속 관계 안에서만 사용 가능

2. 하나 이상의 가상함수를 가지고 있어야 함.

3. 컴파일러의 RTTI 설정이 켜져 있어야 함.


다운 캐스팅 예제:



1. 포인터가 실제로 가리키는 대상이 기본 클래스의 객체면 반환 실패

2. dynamic_cast가 캐스팅 해주는 것은 포인터나 참조자의 타입을 다운 캐스팅 하는 것. 객체의 타입 캐스팅은 못함.

3. dynamic_cast는 캐스팅에 실패할때 포인터면 널 리턴, 참조자면 bad_cast 예외 던짐

 = > 이것이 안전한 타입 캐스팅의 의미


크로스 캐스팅 예제:



1. 각 기본 클래스 포인터 타입의 컨테이너 혹은 배열을 운용하면서 서로간의 요소 교환시 사용 가능.


다중 상속은 그렇게 권장하지 않는 방식이다.


static_cast


기본적으로  C 스타일 캐스팅과 가장 비슷한 기능임.

C 스타일 캐스팅처럼 만능이 아니고 4가지의 캐스트 연산자로 분리된 만큼 const_cast의 역할인 상수성 날린다 던가 다른 캐스트들의 기능을 따라하진 못함. 다른 캐스트 연산자와 같이 static_cast도 static_cast만의 용도가 있음.


제약 사항


1. 실수형과 정수형, 정수형과 열거형 등의 기본 데이터 타입간의 변환

2. 상속 관계의 클래스 계층 간의 변환

 - 런타임 타입 검사를 안함

 - 다형성이 없어도 변환 가능 (RTTI 옵션이 꺼져 있어도 됨.)

 - 다중 상속에서 기본 클래스 간의 타입 변환 못함

3. void 포인터를 다른 타입의 포인터로 변환

4. 서로 다른 타입의 포인터 간의 타입변환 불가


서로 다른 타입의 포인터 간의 타입 변환에는 reinterpret_cast를 쓰는 것 보다 void 포인터 경유 방식 추천한다.




reinterpret_cast


거의 C 스타일의 캐스팅과 같은 만능인 캐스팅.

이 캐스트 연산자는 C 스타일 만큼은 아니지만 거의 다 가능함.

캐스팅 대상을 캐스팅 타겟 타입으로 비트 단위로 다시 만들어 버림


단, 상수성 의 경우는 불가


제약 사항


1. 전혀 관계없는 타입 변환

 - 상속관계 없는 클래스 간의 변환

2. const_cast 기능 제외

3. C 캐스팅 연산자 만큼 위험함. 컴파일러 마다 결과가 다를 수 있어 이식성이 낮음



reinterpret_ptr은 비트 단위로 다시 주소 영역에 새로 쓰기때문에 굉장히 위험도가 크고, 이식성도 낮다.

그래서 사용을 권장하지 않는다.

댓글

댓글쓰기 폼

VallistA

병특이 끝나서 게임에서 웹으로 스위칭한 프로그래머.
프로그래밍 정보등을 공유합니다.

자고 싶습니다. ㅠㅠ

페이스북    :: 링크
카카오톡    :: kingbye1
Github      :: 링크

궁금한점 문의 주시면 답변드리도록 하겠습니다

VISITED

Today : 36

Total : 391,408

SNS

  • 페이스북아이콘
  • 카카오톡아이콘
  • 트위터아이콘