Cpp06
Younji Kim / August 2022
CPP06에 관한 정리글. 정적 형변환과 동적 형변환에 대해 연습한다.
Table of contents
직렬화란?
직렬화의 뜻은 어떤 데이터를 다른 곳에서 사용할 수 있게 다른 포맷의 데이터로 바꾸는 것을 의미한다. ex01에서 직렬화와 역직렬화를 시키는데, 이는 reinterpret_cast를 통해 가능하다.
- uintptr_t 타입은 void 포인터에서 변환된 값을 보유하고 원래 포인터와 동일한 값으로 해당 유형으로 다시 변환할 수 있는 정수 유형이다.
- reinterpret_cast : 타입캐스트 연산자 중 하나. reinterpret_cast
(바꿀대상)으로 실행한다. 이 연산자는 임의의 포인터 타입끼리 변환을 허용하는 캐스트 연산자이다. 일반적으로 허용하지 않는 위험한 형변환을 실행할 때 사용한다. (void *)로도 전달이 가능하기 때문에 특수한 경우에 쓰인다. 또한 정수형을 포인터로 바꿀 수 있기 때문에 ex01 과제에서 이를 사용하였다.
타입캐스트 연산자
- static_cast<바꿀 타입="">(바꿀 대상); 의 형태를 가진다. compile 타임에서 형변환에 대한 타입 오류를 잡아준다. 업캐스팅과 다운캐스팅을 모두 허용하는 캐스팅 연산자이다. dynamic_cast보다 유하긴 하나, C에서 쓰던 강제 형변환보다는 조금 엄격하다. static_cast는 기본자료형의 형변환과 다운캐스팅/업캐스팅을 모두 허용하지만 일반적이지않고 괴상한 캐스팅은 허용하지 않는다.바꿀>
- dynamic_cast는 서로 상속 관계에 있는 클래스 간의 형변환에 사용한다. 업캐스팅은 허용하지만 다운캐스팅은 허용하지 않는다는 것을 알 수 있다. 만약 기초 클래스가 다형성이 적용된 클래스(하나 이상의 가상 함수를 가질 경우)이면 RTTI(Runtime Type Information)을 가지기 때문에 다운캐스팅을 할 수 있다. RTTI는 런타임시 캐스팅하는 dynamic_cast에게 제공되는 객체의 정보를 말한다.
업캐스팅과 다운캐스팅
Base* b = new Derived;
이 코드는 아무 문제 없이 실행이 된다. 바로 업캐스팅 기능 덕분이다. 메모리 어딘가에 Derived 타입을 가진 객체가 생성이 되고 그 객체에 대한 포인터를 리턴해서 부모클래스의 포인터가 받는 형태이다. 즉 묵시적으로 자식 클래스로부터 부모 클래스로의 형변환이 일어나기 때문에 부모클래스를 가리키는 포인터에 대입이 가능한 것이다. 이렇게 부모<-자식로 올라가는 묵시적인(눈에 안보이는) 캐스팅을 업캐스팅이라고 한다. 업캐스팅은 자식클래스가 가지고 있는 속성이 부모보다 많이 때문에 평상시에 문제가 되지 않는다.
예를 들어 기본 클래스와 상속을 받은 파생 클래스가 있을 때 기본 클래스가 파생클래스의 함수를 쓰려고 하면 오류가 난다. 그럴 때 기본 클래스 인스턴스를 파생클래스 타입으로 형변환함으로써 해결한다.
반면, 자식<-부모로 내려가는 캐스팅을 다운캐스팅이라고 한다.
class Base {
public:
int a = 1;
};
Base* b = new Drived; b->a;
이 함수를 실행했을 때, Drived를 참조하는 포인터 b가 상속받은 a에 접근하려고 한다. 이럴 때는 Drived를 가리키고 있어도 부모의 a밖에 접근을 못한다. 그럼 b를 통해 Drived의 고유 멤버들에 접근하려면 다운캐스팅이 필요하다.
출처
https://sexycoder.tistory.com/15