C++ Type cast Operator 및 상수 포인터
2025. 9. 9. 21:47ㆍ개발/C,C++
int a = 10;
float b = 3.14f;
float c = a; // int → float (암묵적 변환)
int d = (int)b; // float → int (C 스타일 캐스트)
int e = static_cast<int>(b); // float → int (C++ 스타일)
요즘 C/C++을 많이 놓고 있고 개발 감을 잃고 있는 것 같아서 관련해서 이전에 작업했던 것들을 리팩토링하며 다시 포스팅을 해보려고한다.

일단 C++에서만 있는 것이 Cast Operator이다.
구분 C 스타일 C++ 스타일
| C언어 스타일 | C++ 스타일 | |
| 비트 재해석 | (int*)&float_var | reinterpret_cast<int*>(&float_var) |
| 포인터 타입 변경 | (T*)ptr | reinterpret_cast<T*>(ptr) |
| 안전성 | ❌ 낮음 (컴파일러 무시함) | ✅ 상대적으로 높음 (컴파일러 체크) |
| 사용 방식 | 자유롭지만 위험 | 명시적으로 위험 표시 |
물론 TypeCast는 보안코딩에서 지양할 점을 가지고 있지만, 개발자의 입장에서는 라이브러리에 포함된 함수들에 들어가는 input, output 값이 다를 수 밖에 없고 그때마다 typecast를 써야하는 경우가 잦다.
항상 깜빡하는 개념이기 때문에 다시 개념을 뽀개기 위해 작성해본다.
- static_cast
- const_cast
- reinterpret_cast
- dynamic_cast
const_cast
const, volatile 등의 키워드를 잠시 지워준다.
static/dynamic cast는 상속을 다루기 때문에 한눈에 차이를 보고자 한번에 설명하도록 함.
class Animal {
public:
virtual void speak() {}
virtual ~Animal() {}
};
class Dog : public Animal {
public:
void bark() {}
};
class Cat : public Animal {
public:
void meow() {}
};
static_cast
Animal* animal = new Dog();
Dog* dog = static_cast<Dog*>(animal); // OK: 실제로 Dog를 가리킴
dog->bark(); // OK
Animal* unknown = new Cat();
Dog* fakeDog = static_cast<Dog*>(unknown); // ❗ 컴파일 OK, 런타임 UB 가능
fakeDog->bark(); // ❌ 잘못된 타입이므로 이상한 동작 or crash
업캐스팅 / 다운캐스팅이 가능
그리고 숫자로 형변환이 가능하다.
dynamic_cast
Animal* animal = new Dog();
Dog* dog = dynamic_cast<Dog*>(animal); // OK
if (dog) dog->bark(); // 안전하게 사용
Animal* unknown = new Cat();
Dog* fakeDog = dynamic_cast<Dog*>(unknown); // ❌ nullptr 반환
if (!fakeDog) std::cout << "Not a dog.\n"; // 안전하게 실패 감지
reinterpret_cast
포인터를 다른 포인터 타입으로 변환한다.
다른건 다 그대로이고, 해석만 달리 한다는 의미이다.
pcap_t* handle = pcap_open_live(dev, BUFSIZ, 1, 1, errbuf);
int res = pcap_sendpacket(handle, reinterpret_cast<const u_char*>(&packet), sizeof(EthArpPacket));
번외 C언의의 Type cast 방식
void print_float_bits(float f) {
// reinterpret 방식: float* → uint32_t*로 캐스팅 후 역참조
uint32_t bits = *(uint32_t*)&f;
}
상수 포인터 관련 이야기
https://coding-factory.tistory.com/660
아래는 윗 글 내용 정리
//non const 포인터
int* ptr = &a;
ptr = &b; //주소 변경 가능
*ptr = 300; //값 변경 가능
//상수 포인터(const pointer)
int* const ptr2 = &a;
ptr2 = &b; //포인터가 상수이므로 변경 불가능
*ptr2 = 300; //값은 변경 가능
int* const ptr = &a;
//상수에 대한 포인터
const int* ptr2 = &a;
ptr2 = &b; //포인터가 상수가 아니므로 변경 가능
*ptr2 = 300; //가리키는 값이 상수이므로 변경 불가능
const int* ptr = &a;
//상수에 대한 상수 포인터
const int* const ptr2 = &a;
ptr2 = &b; //포인터가 상수이므로 변경 불가능
*ptr2 = 300; //가리키는 값이 상수이므로 변경 불가능
const int* const ptr = &a;