#include <iostream>
#include<iomanip>
using namespace std;
// 캐스팅 (타입 변환)
class Player {
public:
virtual ~Player() {
}
};
class Knight :public Player{
};
class Archer :public Player {
};
class Dog {
};
// 1) static_cast
// 2) dynamic_cast
// 3) const_cast
// 4) reinterpret_cast
//이 함수가 외부함수라고 가정
//즉 수정이 불가함
void PrintName(char* str) {
cout << str << endl;
}
int main()
{
// static_cast : 타입 원칙에 비춰볼 때 상식적인 캐스팅만 허용해준다
// 1) int <-> float
// 2) Player* -> Knight* (다운캐스팅) << 단 , 안정성 보장 못함
int hp = 100;
int maxHp = 200;
float ratio = static_cast<float>(hp) / maxHp; //int 와 int의 나눗셈은 주의를 해야함
//부모 -> 자식 자식 -> 부모
Player *p= new Player();
Knight* k1 = static_cast<Knight*>(p);
Knight* k = new Knight();
Player* p2 = static_cast<Player*>(k1);
Player* Ap = new Archer();
// dynamic_cast : 상속 관계에서의 안전 형 변환
// RTTI (Runtime Type Information)
// 다형성을 활용하는 방식
// - virtual 함수가 하나라도 있으면 객체의 메모리에 가상 함수 테이블 (vftable) 주소가 기입된다.
// - 만약 잘못된 타입으로 캐스팅을 했으면, nullptr을 반환 **중요**
// 이를 이용해서 맞는 타입으로 캐스팅을 했는지 확인할 때 유용함
Knight* k2 = dynamic_cast<Knight*>(Ap); //archer -> knight로 캐스팅하는 잘못된 방식
// const_cast : const를 붙이거나 떼거나 할 때 사용
//PrintName("LeeSY"); //이 경우 const를 떼야함
PrintName(const_cast<char*>("LeeSY")); //const를 뗀다고 명시적으로 정의
// reinterpret_cast
// 가장 위험하고 강력한 형태의 캐스팅
// 're-interpret' : 다시 간주하다/ 생각하다
// - 포인터랑 전혀 관계없는 다른 타입 변환 등
__int64 address = reinterpret_cast<__int64>(k1); //나는 k2의 주소를 알고싶다!
cout << address << endl;
Dog* dog1 = reinterpret_cast<Dog*>(k2);
void* p = malloc(1000); //void* 의 뜻 : 니가 알아서 변환해서 사용해줘
Dog* dog2 = reinterpret_cast<Dog*>(p);
return 0;
}