42seoul/circle-4

[ CPP06 ] 0. 과제이해하기

saniii 2022. 8. 6. 00:49

 

 

타입 캐스트에 대해서 알아봅시다. 

 

  • 업캐스팅
    • 자식클래스 객체를 부모클래스의 포인터로 가리키는 것
    • (부모클래스) *(변수) = (자식 클래스 객체);
    • 위의 변수로는 자식클래스 객체에서 부모클래스의 public에 해당하는 멤버만 접근할 수 있다. 
  • 다운캐스팅
    • 부모 클래스 포인터가 가리키는 객체를 자식 클래스의 포인터로 가리키는 것
    • (자식 클래스 포인터 변수) = (자식 클래스 *)(부모 클래스 포인터 변수);
      • 명시적으로 형변환을 해야한다. 
    • 다운캐스팅시 부모클래스 포인터 변수가 부모클래스 객체를 가리키고 있을때 위와 같이 형변환하고 자식 클래스의 멤버를 호출하면 컴파일시에는 문제가 없지만 실행 중에 오류가 발생할 수 있어 위험하다. 
  • type casting : 변수의 type을 강제로 변환하는 것
    • 묵시적
    • 명시적 : c스타일
    • _cast : c++ 스타일로 보다 안전한 형변환을 지원한다. 

ex00  

 

string 표현의 파라미터를 받아서 c++의 가장 흔한 형식으로 바꾸는 프로그램을 만들어라. 이 literal은 char, int, float, double과 같은 스칼라 유형중 하나에 속해야한다. char을 제외하고는 십진수로 표기한다. 

 

Examples of char literals: ’c’, ’a’, ...

To make things simple, please note that non displayable characters shouldn’t be used as inputs. If a conversion to char is not displayable, prints an informative message.

 

Examples of int literals: 0, -42, 42...

 

Examples of float literals: 0.0f, -4.2f, 4.2f... You have to handle these pseudo literals as well (you know, for science): -inff, +inff and nanf.

 

Examples of double literals: 0.0, -4.2, 4.2... You have to handle these pseudo literals as well (you know, for fun): -inf, +inf and nan.

 

 

먼저 파라미터로 받은 literal의 유형을 파악하고 문자열에서 실제 유형으로 변환한 다음 다른 세가지 데이터 유형으로 변환하세요. '명시적으로' 

 

변환이 의미가 없거나, 오버플로우되는 경우에는 유형변환이 불가능함을 알리는 메세지를 출력합니다. 숫자 한계나 특수값을 처리하는 헤더를 포함해도 됩니다. 


< static_cast >

컴파일(정적)타임에 형변환이 가능한지 검사.

  • static_cast<변환할 타입>(변환하는 대상);
    • 기본 자료형간의 형변환
      • 실수 -> 정수
      • 정수 -> 실수
    • 부모클래스 포인터 -> 부모 클래스
    • 자식 클래스 포인터 -> 자식 클래스
    • 부모 클래스 포인터 -> 자식 클래스 (unsafe)
    • 자식 클래스 포인터 -> 부모 클래스

 

 

 


ex01

 

다음 함수를 구현하세요.

 

uintptr_t serialize(Data* ptr);

- 포인터를 받아서 uintptr_t타입으로 변환하세요.

 

Data* deserialize(uintptr_t raw);

- uintptr_t를 받아서 Data타입으로 변환하세요.

 

만든 함수가 잘 작동하는지 보여줄 수 있는 프로그램을 작성하세요.

 

비어있지 않은 (data 멤버를 가지는) data 구조를 생성해야합니다.

 

data 객체의 주소에 serialize()를 사용했다가 다시 deserialize() 함수를 사용한 값이 원래 포인터와 같다는 걸 보여주세요. 

 


reinterpret_cast<변환할 타입>(변환하는 대상);

  • 포인터, 참조 변수를 형변환한다. 
  • const로 지정한 대상은 변환할 수 없다. 

 

uintptr_t

  • 포인터의 주소를 저장
  • intptr_t의 부호 없는 버전으로 유연성이 떨어지고 제한적이다. 

 


ex02

 

virtual 소멸자만 가지는 base class를 만들고 base class를 상속받는 세개의 빈 클래스 A, B, C를 생성하세요. 

이 4개의 클래스는 OCCP를 지킬 필요가 없습니다. 

 

다음의 함수를 구현하세요. 

 

Base * generate(void);

- A, B, C를 랜덤하게 초기화하고 base 포인터를 리턴해라. 

 

void identify(Base* p);

- p의 실제 타입을 출력해라.

 

void identify(Base& p);

- p의 실제 타입을 출력해라. 이 함수안에서는 포인터를 사용하는 것을 금지한다. 

 


dynamic_cast<변환할 타입>(변환하는 대상);

  • 런타임중에 검사한다. 
  • 부모 클래스에 virtual 함수가 존재해야 한다.
  • Class 포인터, 참조변수간 형 변환할 때 안전한 다운캐스팅을 위해 사용한다. 
    • (상속 관계에서 안전한 형변환을 하고자 할 때)
    • 자식클래스 -> 부모 클래스
    • 하나 이상의 가상함수를 가지면 부모-> 자식 이 가능하다. (안전한 다운캐스팅)

https://blockdmask.tistory.com/241 

 

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=kyed203&logNo=220191953895#:~:text=%EB%B6%80%EB%AA%A8%20%ED%81%B4%EB%9E%98%EC%8A%A4%EC%99%80%20%EC%9E%90%EC%8B%9D%20%ED%81%B4%EB%9E%98%EC%8A%A4,%EC%8B%9C%200%EC%9D%84%20%EB%B0%98%ED%99%98%ED%95%A9%EB%8B%88%EB%8B%A4. 

 

 

 

< 참조 >

https://mynameisdabin.tistory.com/20