본문 바로가기
College Study/C++ (ENG)

[C++] Casting (ENG)

by 2den 2022. 1. 2.
728x90

 

C-style Casting

C-style Casting is an implicit casting.

int score = (int)someVariable;
 

 

 

 

 

static_cast

For Values: static_cast converts two numeric types. It tries to keep the same value between before and after the conversion. So the binary representations can be different.

int number1 = 3;                              // 0000 0000 0000 0011
short number2 = static_cast<short>(number1);  //           0000 0011
 
float number1 = 3.f;                          // 0100 0000 0100 0000
int number2 = static_cast<int>(number1);      // 0000 0000 0000 0011
 

 

For Object Pointer: static_cast checks the variable type and converts the parent class to a child class. Type checking is possible only at compile time. Crash can occur during execution.

Animal* myPet = new Cat(2, "Coco");     // Animal*

Cat* myCat = static_cast<Cat*>(myPet);  // Animal* to Cat* - OK

// compiler checks only whether they are in inheritance relationship
Dog* myDog = static_cast<Dog*>(myPet);  // Animal* to Dog* - OK
myDog->GetDogHouseName();

House* myHouse = static_cast<House*>(myPet);  // Compile Error
myHouse->GetAddress();
 

 

 

 

reinterpret_cast

reinterpret_cast allows type conversion between two pointer types even if they are not related. And it also allows type conversion between a pointer and non-pointer. The binary representations of them are not different.

// 1111 1111 1111 1111 1111 1111 1111 0110
int* signedNumber = new int(-10);

// unsigned int: zero and positive numbers (0 ~ 4,294,967,295)
unsigned int* unsignedNumber = reinterpret_cast<unsigned int*>(signedNumber);  // 4294967286
 
Tiger* tiger = new Tiger(5);

unsigned int intAddress = reinterpret_cast<unsigned int>(tiger);

tiger = reinterpret_cast<Tiger*>(intAddress);
tiger->Roar();
 

 

 

 

const_cast

const_cast can't convert types. It is used to eliminate const or votile attribute.

Animal* myPet = new Cat(2, "Coco");
const Animal* petPtr = myPet;

Animal* myAnimal = const_cast<Animal>(petPtr);  // OK
Cat* myCat = const_cast<Cat*>(petPtr);          // Compile Error
 

Except the situation that you have to use the third-party library without const parameter, it's better to not use the const_cast.

void WriteLine(char* ptr);         // external library

void MyWriteLine(const char* ptr)  // my code
{
    WriteLine(const_cast<char*>(ptr));
}
 

 

 

 

dynamic_cast

Animal* myPet = new Cat();

// Compiles, and returns NULL
Dog* myDog = dynamic_cast<Dog*>(myPet);

// Compiles, GetHouseName() will not execute
if (myDog != NULL)
{
    myDog->GetHouseName();
}
 

dynamic_cast check the types while running. It can be used when casts pointer types or reference types. It returns NULL when converting to incompatible child type. So it is safer than static_cast.

 

But to use dynamic_cast, you have to turn on RTTI (Real-Time Type Information). Most of C++ projects turn off this. (and exception) If the RTTI is tured off, dynamic_cast and static_cast works the same.

 

 

Best Practice

1. First use static_cast.

- Using static_cast instead of reinterpret_cast can make compiler give error so that you can check one more time.

 

2. Use reinterpret_cast only when you need.

- Conversion between a pointer and a non-pointer is sometimes needed.

- Conversion between pointers that are not related should be used when you're sure of the data type.

 

3. Use const_cast only when calls immutable extarnal libraries.

 

728x90

댓글