1. static_cast

논리적으로 가능한 캐스팅만 허용

1) int <-> float

int main()
{
    int hp = 100;
    int maxHp = 200;
    float ratio = hp / maxHp;
}

위 처럼 둘 다 int 형인 값을 나누면 결과도 int 형으로 나온다.

int main()
{
    int hp = 100;
    int maxHp = 200;
    float ratio = static_cast<float>(hp / maxHp);

    return 0;
}

따라서 결과를 static_cast<float>(  )를 이용하여 float 타입으로 바꿔준다.

 

2) 상속 관계에 있는 클래스 (부모* -> 자식* ; 다운캐스팅)

    Player* p = new Knight();
    Knight* k1 = static_cast<Knight*>(p);

p에 새로운 Knight 객체의 포인터를 저장시키고 p의 타입을 Knight로 변경한 후 k1에 대입한다(부모 -> 자식).

그러나, 다운 캐스팅을 하더라도 이 구문의 안정성은 보장해줄 수 없다.

 

2. dynamic_cast

상속 관계에서 안전하게 형 변환.

RTTI(Runtime Type Information) ; 실시간으로 데이터의 타입을 구함.

VFTBL(Virtual Function Table ; 가상 함수 테이블)을 활용하여 다형성을 구성함.

RTTI 정보는 VFTBL에 저장되어 있으며, 다형성을 구성하기 위해 가상 함수(Virtual Function)을 사용한다.

 

따라서 부모 클래스 내부에 가상 함수를 만들어주면 객체의 메모리에 가상 함수 테이블의 주소가 기입된다. 그리고 이 가상 함수 테이블에 RTTI 정보가 있다.

이를 통해 자식 클래스의 포인터가 올바르게 자신을 가리키게 된다.

 

가상 함수를 클래스 내에 포함하지 않으면 RTTI 정보를 갖지 않게 되고, 자식은 비 다형성 객체가 된다(포인터가 부모 클래스를 가리킨다).

 

잘못된 타입으로 캐스팅이 되었다면 nullptr을 반환한다.

이를 이용하여 맞는 타입으로 캐스팅을 했는지 확인할 수 있다.

 

3. const_cast

const를 붙이거나 뗄 때 사용.

아래와 같이 char 형식의 문자열을 받아 출력하는 함수를 하나 만든다.

void PrintName(char* str)
{
    cout << str << endl;
}
    PrintName(const_cast<char*>("Crat"));

여기에서 "Crat" 문자열은 Const char 형 이기 때문에, char 타입인 함수 PrintName을 사용하려면 Const 형을 제거해 줄 필요가 있다.

따라서 const_cast<char*>를 이용하여 해당 문자열을 char 타입으로 변환한다.

 

4. reinterpret_cast

위험하고 강력한 형태의 캐스팅.

포인터와 전혀 관계없는 타입으로 변환할 때 사용.

이 변환이 수행될 때, 컴파일러는어떤 검사도 수행하지 않으며, 단순히 포인터 값을 새로운 타입으로 해석하게 된다.

 

'기초 C++ 스터디 > 객체지향' 카테고리의 다른 글

8-1. 함수 포인터(1)  (0) 2023.06.08
6-7. 전방 선언 vs 포함(#include)  (0) 2023.06.05
6-4. 얕은 복사, 깊은 복사  (0) 2023.06.01
6-3. 형(Type) 변환 : 포인터 (2)  (0) 2023.06.01
6-2. 형(type) 변환 (1)  (0) 2023.05.31