C++

타입 캐스팅

팀(Tim) 2020. 10. 27. 01:42

타입을 변경하는 것.

 

C스타일 형변환

강제 형변환이다.

(int)'A' 처럼 쓴다.

형변환이 불가능해도 경고가 나지 않으니 주의해야한다.

만약 잘못쓰면 힙이 오염된다.

 

static_cast

컴파일타임에 확인할 수 있는 요소를 고려해 캐스팅을 하는 것.(정적)

논리적인 형변환을 해준다. 

예를들어,

1. int* 를 int로 형변환하는 것을 막아준다.

2. 부모와 자식사이가 아닌 클래스끼리의 형변환을 막아준다. (상속확인)

 

하지만 2번에서, 뭐가 부모고 뭐가 자식인지는 신경쓰지 않고 형변환을 진행한다. 

즉, 위험한 상황이 발생할 수 있다.

왜냐하면 부모는 A,B의 기능을 가지고 있고 자식은 A,B,C,D의 기능을 가지고 있는데

부모를 자식으로 형변환한다하면, 부모에게 없는 기능인 C,D를 사용하려고 했을때

 허용되지 않은 접근이 일어날 수 있다.



dynamic_cast

컴파일타임 + 런타임에 확인할 수 있는 요소를 고려해 캐스팅을 하는 것.(동적)

상속 유무는 물론이고 부모 자식의 관계까지 고려한다.

만약 부모 자식이 다형성을 적용할 수 있는 관계면 다이나믹 캐스팅을 통해 다운캐스팅을 할 수 있다.

다이나믹 캐스팅은 실객체가 무엇인지를 판단한다. 

최상위 클래스인 Obj*를 함수의 인자로 받는다고 했을때, 그 인자에 어떤 Obj

 자식 클래스가 올지는 런타임에 정해진다.

따라서 이때는 동적캐스팅이 필요한 것이다. 

인자는 Obj로 받지만 실제로 인자로 들어온 것은 Obj 자식클래스가 될 수 있는 것이다. 

그럼 이 CObj*가 가리키는 실객체는 Obj 자식클래스다. 이 인자(CObj*타입)를 

하위클래스로 동적 캐스팅했을시,

성공하면 유효한 주소가 반환되고, 실패하면 nullptr이 반환된다.

따라서 nullptr이 반환됬을때도 뜻하지 않은 동작을 하지 않도록 if문으로 체크해야한다.  

ex) if(결과주소) {}

주의할 점으로, 다이나믹 캐스팅은 다형 관계에 있는 클래스끼리의 형변환만 지원한다는 것이다.

즉, 클래스에 virtual 키워드가 붙은 함수가 하나이상 있어야한다는 것이다.

virtual이 있는 클래스는 컴파일 타임에 type_info 라는 타입정보가 생성이 됨. 다이나믹 캐스팅은

이 멤버를 이용해 실객체를 판단한다.

 

또한 다이나믹 캐스팅은 일반자료형이나 일반 포인터를 대상으로 하지 않는다. 오로지

 객체 포인터간의 형변환만 가능하다.

 

const_cast

상수 포인터나 상수 레퍼런스를 상수가 아닌 포인터나 레퍼런스로 만드는 형변환.

 

reinterpret_cast

const 포인터를 제외한 모든 포인터에 대한 형변환.