C++ 에서의 형 변환 연산
Programming/C++ 2012. 10. 31. 14:46 |C++ 에서 C 스타일의 형 변환 연산자를 가리켜 '오래된 C 스타일 형 변환 연산자(Old C-style cast operator)' 라 부른다. 이렇듯 C 스타일의 형 변환 연산자는 C언어와의 호환성을 위해서 존재할 뿐, C++에서는 새로운 형 변화 연산자와 규칙을 제공하고 있다 .
40행: 문제가 없어 보이기도 하다. 하지만 기초 클래스의 포인터 형을 유도 클래스의 포인터 형으로 형 변환하는 것은 일반적인 경우의 형 변환이 아니다.
이 예제의 문제점은 40행에 있다. 이것이 실수인지 아니면 일부러 이렇게 했는지 그 의도를 모르기 판단하기 힘들기 때문이다.
그래서 이러하 유형으 논란과 문제점 때문에 C++ 에서는 다음과 같이 총 4개의 연산자를 추가로 제공하면서 용도에 맞는 형 변환 연산자의 사용을 유도하고 있다.
static_cast
const_cast
dynamic_cast
reinterpret_cast
위의 형 변환 연산자들을 사용하면 프로그래머는 자신이 의도한 바를 명확히 표시할 수 있다. 따라서 컴파일러도 프로그래머의 실수를 지적해 줄 수 있고, 코드를 직접 작성하지 않은 프로그래머들도 코드를 직접 작성한 프로그래머의 실수여부를 판단할 수 있다.
dynamic_cast : 상속관계에서의 안전한 형 변환
dynamic_cast<T>(expr)
즉, <> 사이에 변환하고자 하는 자료형의 이름을 두되, 객체의 포인터 또는 참조형이 와야 하며, () 사이에는 변환의 대상이 와야 한다.
※ dynamic_cast 연산자를 사용하겠다는 것은 다음의 의미가 담겨있다.
- 상속관계에 있는 유도 클래스의 포인터 및 참조형 데이터를 기초 클래스의 포인터 및 참조형 데이터로 형 변환하겠습니다.
※ 43행의 형 변환은 의도적으로라도 하면 안된다. 그러나 40행 같은 경우에는 경우에 따라서 필요할 것도 같다. 이러한 경우엔 어떻게 해야 하나?
- 이러한 형 변환을 의도적으로 진행한다는 것을 명시하기 위하 형 변환 연산자를 사용해야 한다. 그리고 그에 맞는 형 변환 연산자가 바로 static_cast 연산자이다.
static_cast : A타입에서 B타입으로
static_cast<T>(expn)
이것은, 유도 클래스의 포인터 및 참조형 데이터를 기초 클래스의 포인터 및 참조형 데이터로뿐만 아니라, 기초 클래스의 포인터 및 참조형 데이터도 유도 클래스의 포인터 및 참조형 데이터로 아무런 조건 없이 형 변환시켜 준다.
하지만 그데 대한 책임은 프로그래머에게 있다.
43행 같은 경우에는 어떻게 해서든 정당화될 수 없는 상황이다. 따라서 이러한 형태로 문장을 구성하면 안된다. 하지만 static_cast는 dynamic_cast와 달리 이것 또한 허용한다.
즉, static_cast 연산자는 dynamic_cast 연산자와 달리, 보다 많은 형 변환을 허용한다. 하지만 그에 따른 책임도 프로그래머가 져야 하기 때문에 신중하게 선택해야 한다.
dynamic_cast 연산자를 사용할 수 있는 경우에는 dynamic_cast 연산자를 사용해서 안전성을 높여야 하며, 그 이외의 경우에는 정말 책임질 수 있는 상황에서만 제한적으로 static_cast 연산자를 사용해야 한다.
※ 보다 빠른 static_cast 연산자
- dynamic_cast 연산자보다 static_cast 연산자를 사용했을 때 연산의 속도가 더 빠르다. 따라서 이러한 이유로 dynamic_cast 연산자를 사용해도 되는 상황에서 조차 static_cast 연산자를 사용하는 경우도 적지 않다.
static_cast 연산자는 기본 자료형 데이터간의 형 변환에도 사용이 된다.
static_cast 연산자는 '기본 자료형 간의 형 변환'과 '클래스의 상속관계에서의 형 변환'만 허용을 하지만, C언어의 형 변환 연산자는 다음과 같이 말도 안되는 형 변환도 허영하기 때문에 여전히 static_cast 연산자의 사용은 의미를 갖는다.
위에서 보인 형 변환은 static_cast 연산자로는 불가능한 형 변환이다. 즉, 여전히 static_cast 연산자는 C언어의 형 변환 연산자보다 적은 것을 허용하고 있으며, 이로 인해서 static_cast 연산자를 보는 순간 다음과 같이 판단할 수 있다.
"상속관계에 있는 클래스의 포인터 및 참조형 데이터의 형 변환인가? 아니면 기본 자료형 데이터의 형 변환인가?"
const_cast : const의 성향을 삭제하라.
C++에서는 포인터와 참조자의 const 성향을 제거하는 형 변환을 목적으로 다음의 형 변환 연산자를 제공하고 있다.
const_cast<T>(expn)
참조자, 포인터의 const 성향을 제거하는 것이 가치를 떨어뜨릴 수 있다. 허나, 다른 이면에선 나름의 의미를 발견할 수 있다. 위의 예제처럼.
이렇듯 const_cast 형 변환 연산은, 함수의 인자전달 시 const 선언으로 인한 형의 불일치가 발생해서 인자의 전달이 불가능한 경우에 유용하게 사용이 된다.
※ 위 예제에서 보이는 것과 같이 const_cast 연산자의 긍정적인 측면이 잘 드러나는 경우에만 제한적으로 사용해야 한다.
const_cast 연산자는 volatile(컴파일러의 최적화를 제한하는 목적) 의 성향을 제거하는데도 사용할 수 있다.
reinterpret_cast : 상관없는 자료형으로의 형 변환
reinterpret_cast 연산자는 전혀 상관이 없는 자료형으로의 형 변환에 사용이 되며, 기본적인 형태는 다음과 같다.
reinterpret_cast<T>(expn)
reinterpret_cast 연산자는 포인터를 대상으로 하는, 그리고 포인터와 관련이 있는 모든 유형의 형 변환을 허용한다.
7행: int 형 정수에 바이트 단위 접근을 위해서 int형 포인터를 char형 포인터로 형 변환하고 있다.
10행: 바이트 단위 데이터를 문자가 아닌 정수의 형태로 출력하기 위해서 char형 데이터를 int형으로 변환하고 있다.
reinterpret_cast 연산자는 포인터와 관련이 있는 모든 유형의 형 변환을 허용한다고 했다.
따라서 다음과 같은 문장의 구성도 가능하다.
위 예제의 경우에 크게 의미를 부여하기 어렵지만, 특정 상황에서는 이러한 유형의 연산이 유용하게 사용되기도 하며, 이는 reinterpret_cast 연산자가 포인터와 관련이 있는 모든 유형의 형 변환을 허용한다는 사실을 뒷받침하기도 한다.
'Programming > C++' 카테고리의 다른 글
C++ Language Tutorial 사이트 (0) | 2012.11.20 |
---|---|
dynamic_cast : Polymorphic 클래스 기반의 형 변환 (0) | 2012.10.31 |
예외처리와 관련된 또 다른 특성들 (0) | 2012.10.30 |
예외상황을 표현하는 예외클래스의 설계 (0) | 2012.10.24 |
하나의 try 블록과 다수의 catch 블록 (0) | 2012.10.24 |