CPP Module 06

hhkim·2022년 6월 21일
0

42cursus

목록 보기
15/20
post-thumbnail

ex00 - Conversion of scalar types

개념

스칼라 타입(Scalar type)

  • 하나의 속성만을 가진 값
  • int, char, float, double 등 하나의 수로 표시될 수 있는 기본 타입
  • = 연산자로 서로 변환이 가능

타입 변환

https://cplusplus.com/doc/tutorial/typecasting/
C++에서 다른 타입끼리의 연산은 피연산자를 모두 같은 타입으로 만든 후에 수행

묵시적 타입 변환(자동 타입 변환)

다른 타입끼리 대입, 산술 연산 수행 시 컴파일러가 자동으로 하는 타입 변환

  • 대입 연산 시 연산자 오른쪽의 데이터 타입이 왼쪽의 타입으로 변환됨
  • 산술 연산 시 데이터 손실이 최소화되는 방향으로 변환됨
    char형 → short형 → int형 → long형 → float형 → double형 → long double형

명시적 타입 변환(강제 타입 변환)

타입 캐스트(cast) 연산자를 사용하여 강제로 수행하는 타입 변환

***_cast<타입>(표현식)
  1. static_cast: 논리적으로 변환 가능한 타입을 변환
  • 컴파일 시점에 발생 (묵시적 타입 변환과 같은 맥락)
  • 상속 관계의 포인터끼리 변환 가능
  1. reinterpret_cast: 임의의 포인터끼리 변환 허용
  • 연관성이 없는 포인터 타입의 변환 가능 (static_cast와 다르게 가능!)
  • 강제 타입 변환으로 가능하게 할 뿐, 안전을 보장하지는 않음
  • 비트 단위로 강제 타입 변환
  • 주로 정수형과 포인터끼리 변환하는 작업에 주로 사용
int num;
int* pNum;
num = reinterpret_cast<int>(&pNum);
  1. const_cast: constvolatile 속성을 잠시 제거
  • 동일한 타입의 포인터, 참조형에 대해서만 사용
  1. dynamic_cast: 상속 관계에 있는 클래스 간 타입 변환
  • 런타임에 캐스팅이 가능한지를 검사하기 때문에 안전한 다운캐스팅, 업캐스팅에 사용

구현

문자열을 인자로 받는 프로그램 작성

  • 이 문자열은 C++의 char, int, float, double 중 하나로 변환될 수 있어야 함
  • char를 제외하고 나머지는 모두 10진수
  • 먼저 인자로 입력된 리터럴의 타입을 알아낸 후 세 가지 다른 데이터형으로도 변환하여 출력
  • 결과를 도출할 수 없거나 오버플로우가 발생하는 경우 impossible 출력
    • numeric limits와 special values를 위한 헤더를 포함할 것
./convert 0
char: Non displayable
int: 0
float: 0.0f
double: 0.0
./convert nan
char: impossible
int: impossible
float: nanf
double: nan
./convert 42.0f
char: '*'
int: 42
float: 42.0f
double: 42.0

string 👉 int, float, double 변환 함수 사용 가능
👉 <cstdlib>atoi(), atof(), strtol()

예시

  • char: c, a, ...
    • 출력되지 않는 문자는 매개변수로 전달할 수 없음 (참고)
  • int: 0, -42, 42, ...
  • float: 0.0f, -4.2f, 4.2f, ...
    • -inff, +inff, nanf도 처리해야 함
  • double: 0.0, -4.2, 4.2, ...
    • -inf, +inf, nan도 처리해야 함

ex01 - Serialization

개념

uintptr_t

https://cplusplus.com/reference/cstdint/
포인터의 주소 저장

  • 시스템 내부의 포인터와 같은 크기
  • 포인터를 정수로 변환할 때 사용
  • void *에서 변환된 값을 가지고, 원래 포인터와 동일한 주소값으로 다시 변환할 수 있음

직렬화 / 역직렬화

  • 객체와 같은 참조형 데이터는 주소를 가지기 때문에 값을 바로 보내는 통신에 사용할 수 없음
  • 직렬화는 각 주소값이 가지는 데이터를 모아서 값 형식 데이터(비트 단위로 길게 나열)로 변환해줌
  • 역직렬화는 반대로 값 형식으로 변환된 데이터를 다시 객체로 변환하는 방식

구현

  • Data는 비어 있지 않은(멤버들을 가지고 있는) 구조체
  • uintptr_t serialize(Data* ptr);: 포인터를 받아서 unsigned integer 타입 uintptr_t로 변환
  • Data* deserialize(uintptr_t raw);: unsigned integer를 받아서 Data *로 변환
  • Data의 주소를 serialize()로 넘기고 그 리턴값을 deserialize()로 넘긴 후 다시 리턴값이 처음 주소와 같은지 비교

ex02 - Identify real type

개념

dynamic_cast

상속 관계에 있는 객체의 포인터나 참조형의 타입 변환

  • 런타임에 캐스트가 실패하는 경우 포인인터 타입은 널 포인터 반환, 레퍼런스 타입은 bad cast exception 예외 발생
  • 업캐스팅에도 사용되지만 안전한 다운캐스팅을 위해서도 사용됨

구현

  • typeinfo 헤더 사용 금지

구현할 클래스들은 Orthodox Canonical Form을 가질 필요 없음

Base 클래스

  • virtual 소멸자만 가짐

A, B, C 클래스

  • Base를 public으로 상속받음

함수

Base * generate(void);
  • 랜덤으로 A B C 중 하나의 객체를 Base *로 리턴
  • 랜덤 함수는 아무거나 사용 가능
void identify(Base* p);
  • p의 실제 타입 표시 (A B C 중 하나)
void identify(Base& p);
  • p의 실제 타입 표시 (A B C 중 하나)
  • 이 함수 내부에서 포인터 사용 금지
    👉 try ~ catch 활용

0개의 댓글