'const_cast'에 해당되는 글 1건

  1. 2012.10.31 C++ 에서의 형 변환 연산

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 연산자가 포인터와 관련이 있는 모든 유형의 형 변환을 허용한다는 사실을 뒷받침하기도 한다.


Posted by scii
: