[C++] CPP Module 06

J_JEON·2022년 12월 22일
0

CPP

목록 보기
7/9

CPP Module 06

  • static_cast, dynamic_cast등 여러종류의 type cast들을 실습

ex00

  • 문자열을 인자로받고 이 문자열을 char, int, float, double로 변환하여 출력
  • 출력할 수 없는 char은 표시할 수 없다고 출력
  • 결과를 도출할 수 없거나 오버플로우가 발생시 impossible 출력
  • +inf, -inf, +inff, -inff, nan, nanf를 입력시 맞게 출력
./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

static_cast

static_cast<바꾸려고 하는 타입>(대상);

  • 형변환시 사용되며 잘못된 형 변환에대한 오류를 체크해줌
  • double -> char 같은 사이즈가 작아지는 상황에서는 값이 사라질 수 있음
  • 일반 포인터의 변환은 안되지만 상속관계의 포인터끼리 변환 가능, 다만 다운캐스트시 안전하지않음

Convert 클래스

class Convertor
{
	private:
		std::string _input;
		int			_type;
		int			_int;
		float		_float;
		double		_double;
		char		_char;
		void startConvert();
		void checkInput();
		float toFloat();
		char toChar();
		double toDouble();
		int toInt();
		Convertor();
	public:
		Convertor(const std::string input);
		Convertor(const Convertor &c);
		Convertor &operator=(const Convertor &c);
		std::string getInput() const;
		float getFloat() const;
		char getChar() const;
		double getDouble() const;
		int getInt() const;
		int getType() const;
		void printConvert();
		~Convertor();
	class excep: public std::exception
	{
		public:
				const char* what( void ) const throw();
	};
};

ex01

  • 구조가 있는 객체의 내용물을 바이트 배열로 저장하는 것을 Serialization이라고 하고 바이트 배열로부터 읽어온 뒤 구조가 있는 객체에 채우는 것을 Deserialization라고 함
  • Data구조체를 uintptr_t형으로 변환한 뒤 다시 Data형으로 변환하고 주소와 데이터가 잘 남아있는지 확인

reinterpret_cast

reinterpret_cast<바꾸려고 하는 타입>(대상);

  • 임의의 포인터간 변환시 사용하는 cast
  • 포인터 -> 포인터, 포인터 -> 일반변수, 일반변수 -> 포인터
  • int* -> char처럼 크기가 작아지면 데이터 손실이 일어남
uintptr_t serialize(Data* ptr)
{
	return(reinterpret_cast<uintptr_t>(ptr));
}

Data* deserialize(uintptr_t raw)
{
	return(reinterpret_cast<Data *>(raw));
}

ex02

  • 가상 소멸자만 소유하는 Base클래스와 이를 상속받는 A, B, C 클래스를 생성
  • A, B, C 클래스를 무작위로 생성하여 반환하는 Base * generate(void);
  • 포인터로 A, B, C클래스를 인자로 받아 해당하는 클래스가 어떤 클래스인지 출력하는 void identify(Base* p);
  • 참조로 A, B, C클래스를 인자로 받아 해당하는 클래스가 어떤 클래스인지 출력하는 void identify(Base& p);
  • <typeinfo>는 사용금지

dynamic_cast

dynamic_cast<바꾸려고 하는 타입>(대상);

  • dynamic_cast는 상속관계에 있는 객체의 포인터나 참조형 타입을 변환할 때 사용함
  • 포인터타입의 dynamic_cast는 타입이 맞지않을경우 NULL을 반환함
  • 참조타입의 dynamic_cast는 타입이 맞지않을경우 bad casting exception을 throw함
void identify(Base* p) // 포인터타입의 dynamic_cast는 타입이 맞지않을경우 NULL을 반환함
{
	if (dynamic_cast<A *>(p) != NULL)
		std::cout << "pointed actual type = A" << std::endl;
	else if (dynamic_cast<B *>(p) != NULL)
		std::cout << "pointed actual type = B" << std::endl;
	else if (dynamic_cast<C *>(p) != NULL)
		std::cout << "pointed actual type = C" << std::endl;
	else
		std::cout << "unknown type" << std::endl;
}

void identify(Base& p) // 참조타입의 dynamic_cast는 타입이 맞지않을경우 bad casting exception을 throw함
{
	try
	{
		A &a = dynamic_cast<A &>(p);
		std::cout << "ref actual type = A" << std::endl;
		(void) a;
		return ;
	}
	catch(const std::exception& e)
	{
	}
	try
	{
		B &b = dynamic_cast<B &>(p);
		(void) b;
		std::cout << "ref actual type = B" << std::endl;
		return ;
	}
	catch(const std::exception& e)
	{
	}
	try
	{
		C &c = dynamic_cast<C &>(p);
		(void) c;
		std::cout << "ref actual type = C" << std::endl;
		return ;
	}
	catch(const std::exception& e)
	{
	}
}
profile
늅늅

0개의 댓글