타입 캐스팅
---------------------------------------------타입 변환 유형---------------------------------------------
1.값 타입 변환
의미를 유지하기 위해서, 원본 객체와 다른 비트열 재구성
int a = 5;
float b = a;
클래스에서는 일반적으로 안 됨 (예외: 타입 변환 생성자, 타입 변환 연산자)
class Dog() {
public:
Dog(const Knight& k){ // 타입 변환 생성
k.age = age_;
}
operator Knight() {return (Knight)(*this)} // 타입 변환 연산자
}
Knight knight;
Dog dog = (Dog)knight;
Knight knight2 = dog;
상속 관계에서는 자식->부모(업캐스팅)는 가능하나 부모->자식(다운캐스팅)은 안됨.
is-a관계를 잘 생각하면 이해가 가능함.
2.참조 타입 변환
특징으로 명시적으로는 참조 타입이 변환됨
Knight knight;
Dog& dog = (Dog&)knight; // knight를 메모리상에서 Dog형식으로 보겠다란 의미로 가능함. 실제로 형식이
// 다르면 메모리 침범에 의해서 매우 위험함
상속 관계에서는 암시적으로는 업캐스팅은 가능하나 다운캐스팅이 안됨 그러나 명시적으로 선언하면 둘 다 가능
BullDog bulldog;
Dog& dog = bulldog; // 불독은 개인가? YES
Dog dog;
BullDog& bulldog = (BullDog&)dog; // 개는 불독인가? 맞을수도 있고 아닐수도 있고 NO 허나 명시적으로 선언하면 가능
결국 값 타입 변환은 논리적으로 말이 되게 비트열을 바꾸거나 대입가능한 것이고,
참조 타입 변환은 포인터를 보는 관점을 바꾸는 느낌이다. 명시적으로 선언시 어떻게든 가능함.
클래스 생성시 암시적 생성자를 컴파일러에서 따로 안보이게 만들어주는데,
기본생성자, 복사생성자, 복사대입연산자 등등이 있음.
생성자를 명시적으로 선언하면 기본 생성자를 암시적으로 생성하지 않는다.
상속받은 클래스의 암시적인 생성자들은 부모 생성자를 호출할 시 그 생성자에 맞게 생성하는데,
예를 들어서 자식클래스의 복사생성자로 생성시, 부모클래스의 복사생성자가 생성되고 자식클래스의 복사생성자가
생성된다.
그러나 자식클래스에서 복사생성자를 명시적으로 선언하여 생성하면 부모클래스는 복사생성자가 아닌 기본생성자를 생성자로 하여 만든다. 결국 선처리영역에서 처리해줘야 하기 때문에 초기화 리스트에 명시적으로 부모클래스의 복사생성자로 생성하게 직접 기입해줘야한다.
이러한 문제는 깊은 복사를 위해서 종종 사용된다.
캐스팅은 c++에서 4가지가 있다.
static_cast : 타입 원칙에 상식적인 캐스팅만 허용 (int <-> float), (클래스의 다운캐스팅) << 단 안전성은 보장 못함.
int hp = 100; int maxHp = 200;
float ratio = static_cast<float>(hp) / maxHp;
-----------------------------------------------------------------
Player* p = new Archer();
Knight* k1 = static_cast<Knight*>(p); // player는 archer지만 knight로 형변환함으로 실제로는 맞지 않음.
dynamic_cast : 상속 관계에서의 안전 형변환에 사용됨. (Runtime Type Information) 다형성을 사용함
클래스에 virtual 함수가 하나라도 있어야함. 잘못된 타입으로 캐스팅시 nullptr반환함.
Knight* k2 = dynamic_cast<Knight*>(p); // p가 원래 Knight타입이라면 (RTTI로 알 수 있음) p를 반환하나
// 다르다면 nullptr 반환
const_cast: const를 붙이거나 떌 수 있음
reinterpret_cast: 가장 위험하고 강력한 형태의 캐스팅 포인터랑 전혀 관계없는 다른 타입 변환 가능
__int64 address = reinterpret_cast<__int64>(k2)
void* p = malloc(1000);
Dog* dog2 = reinterpret_cast<Dog*>(p);
'c++' 카테고리의 다른 글
c++공부(list iterator 구현) (0) | 2025.03.07 |
---|---|
c++ 공부(vector iterator 구현) (0) | 2025.03.06 |
c++ 공부 (0) | 2025.03.01 |
c++ 공부 (0) | 2025.03.01 |
c++ 공부 (0) | 2025.02.27 |