본문 바로가기

C, C++/C, C++ 잡지식

C++ 캐스팅 연산자

개요

C에서는 캐스팅이 단순히 변수 앞에 (타입)을 붙여 컴파일러가 해당 타입에 대해 에러를 내지 않게 하는 것에 그쳤다.

이러한 방법은 너무 강력하기 때문에 C++에서는 세분화한 캐스팅 방법을 제공한다.  

 

1. static_cast

2. dynamic_cast

3. const_cast

4. reinterpret_cast

https://learn.microsoft.com/ko-kr/cpp/cpp/casting-operators?view=msvc-170

 

캐스팅 연산자

자세한 정보: 캐스팅 연산자

learn.microsoft.com


static_cast

static_cast는 '말이 되는' 문법이면 통과시켜준다.

기본형 간 변환, 업캐스팅, enum<->int 등 일반적으로 많이 사용하는 캐스팅에 static_cast를 사용한다.

int _tmain(void)
{
    Base* b = new Base;

    Derived* d = static_cast<Derived*>(b);

    return 0;
}

다만 위와 같은 다운캐스팅의 경우에는 static_cast가 가능하지만, 실제 부모 포인터가 가리키는 객체가 실제로는 어떤 타입일지 알 수 없기 때문에 다운캐스팅에 static_cast를 사용하는 것은 위험할 수 있다.

 

따라서 이러한 경우에는  RTTI(RunTime Type Id)를 사용하는 dynamic_cast를 사용해볼 수 있다.


dynamic_cast

https://learn.microsoft.com/ko-kr/cpp/cpp/run-time-type-information?view=msvc-170

 

 

런타임 형식 정보

다음에 대해 자세히 알아보세요. 런타임 형식 정보

learn.microsoft.com

dynamic_cast는 RTTI를 활용해 다형성, 상속관계 내의 캐스팅이 적절한 지 여부를 런타임에 잡아준다.

만약 해당 클래스가 실제로 캐스팅한 타입과 일치하는지 확인하고, 아니라면 nullptr을 반환해준다.

 

class Base
{
public:
    virtual ~Base()
    {
        cout << "Base" << endl;
    }
};

class Derived1 : public Base
{
    ~Derived1()
    {
        cout << "Derived1" << endl;
    }
};

class Derived2 : public Base
{
    ~Derived2()
    {
        cout << "Derived1" << endl;
    }
};

int _tmain(void)
{
    Base* b = new Derived2;

    Derived1* d1 = static_cast<Derived1*>(b);
    Derived1* d2 = dynamic_cast<Derived1*>(b);

    return 0;
}

현재 위의 코드는 Derived2를 Derived1으로  변경하려고 시도한다. Derived1, Derived2는 Base를 상속받았지만 관계가 없는 객체이다. 따라서 컴파일에는 문제가 없지만, 런타임 실행시에 d2에는 nullptr을 반환하게 된다. 

 

    Derived1* d2 = dynamic_cast<Derived1*>(b);
00B71189 6A 00                push        0  
00B7118B 68 C0 50 B7 00       push        offset Derived1 `RTTI Type Descriptor' (0B750C0h)  
00B71190 68 D8 50 B7 00       push        offset Base `RTTI Type Descriptor' (0B750D8h)  
00B71195 6A 00                push        0  
00B71197 8B 55 F4             mov         edx,dword ptr [b]  
00B7119A 52                   push        edx  
00B7119B E8 F3 15 00 00       call        ___RTDynamicCast (0B72793h)  
00B711A0 83 C4 14             add         esp,14h  
00B711A3 89 45 EC             mov         dword ptr [d2],eax

위와 같이 RTTI를 활용해 type descriptor를 받아오고 이를 인자로 함수를 내부적으로 호출하고 있음을 알 수 있다.

 

런타임 메커니즘이고, 다형성 관계를 파악하는 작업이 필요하므로 이는 실행 중 성능저하를 일으킬 수 있다.

따라서 실제로는 사용을 지양한다.


const_cast

const를 때고 붙일 수 있는 캐스팅 방법

const는 실제로 해당 메모리를 보호하는 등의 행위를 하지 않기 때문에 컴파일러의 에러를 잡는 역할이 끝이다.


reinterpret_cast

 

타입 간의 물리적인 의미는 무시하고 메모리 비트 패턴을 그대로 해석해서 다른 타입으로 변환하는 캐스팅이다.

의미를 정말 잘 파악하고 사용해야 한다.

'C, C++ > C, C++ 잡지식' 카테고리의 다른 글

CreateThread와 _beginthreadex 간단하게 알아보기  (0) 2025.10.08
구조체?  (0) 2025.06.14
가상 함수 virtual  (1) 2025.06.06
malloc과 new, free와 delete  (2) 2025.05.31
동적할당 분석해보기(1)  (0) 2025.05.01