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;