CS/C++

c++ 캐스팅

혀니리리 2023. 12. 14. 11:41
728x90

C++ 캐스팅 총정리(스마트포인터 캐스팅 포함) (ence2.github.io)

 

C++ 캐스팅 총정리(스마트포인터 캐스팅 포함)

캐스트는 자료형간 또는 포인터간 형변환시 사용됩니다. 캐스트는 크게 묵시적 캐스트(implicit cast)와 명시적 캐스트(explicit cast) 두 가지로 나눌 수 있습니다. 특별히 캐스트 연산자를 사용하지

ence2.github.io

[C++] 캐스팅(Casting) (tistory.com)

 

[C++] 캐스팅(Casting)

References Professional C++ https://en.cppreference.com/w/ Contents const_cast() static_cast() reinterpret_cast() dynamic_cast() std::bit_cast() C++에서는 어떤 타입을 다른 타입으로 캐스팅하기 위한, const_cast(), static_cast(), reinterp

junstar92.tistory.com

캐스트는 자료형 간 ,포인터간 형변환시 사용됨

크게 묵시적, 명시적 캐스트로 나눌 수 있음

그리고 4가지로 나눌 수 있음(static_cast / const_cast / reinterpret_cast / dynamic_cast)

 

1.const_cast

변수에 const 속성을 추가하거나 제거할 때 사용

(필요성: 사실 const라는것은 상태를 유지하겠다는 뜻이지만,

실전에서 함수를 작성할 때는 const변수를 인수로 받도록 정의했는데, 하다보니 non_const도 받아야 할 때가 생길 수 있음)

void ThirdPartyLibraryMethod(char* str);

void f(const char* char)
{
	ThirdPartyLibraryMethod(const_cast<char*> str);
}

(서드파티 라이브러리와 같이 마음대로 수정할 수 없을때 부득이 제거하는 예제)

 

2.static_cast

명시적 변환을 수행

int i{3};
int j{4};
double result{static_cast<double>(i) / j};

 

상속 계층에서 다운캐스팅을 수행할 때도 static_cast() 사용 가능

class Base
{
public:
	virtual ~Base() = default;
}

class Derived: public Base
{
public: 
	virtual ~Derived() = default;
}

int main()
{
	Base *b{nullptr};
    Derived* b{new Derived{}};
    b = d;
    d = static_cast<Derived*>(b); //static cast사용
    
    Base base;
    Derived derived;
    Base& br{derived};
    Derived& dr{static_cast<Derived&>(br)};
}

static_cast -> 실행시간에 타입검사를 하지 않음.!

(실행시간에 타입검사하는것: dynaimc_cast())

 

제약이 많음(기본적으로 C++의 타입규칙에서 허용하지 않는 것은 모두 할 수 없음)

포인터의 타입이 서로 관련이 없을 때는 static_cast()를 적용할 수 없음

변환 생성자가 제공되지 않는 타입의 객체에도 static_cast()를 적용할 수 없음

const 타입을 non-const 타입으로 변환할 수도 없고, int에 대한 포인터에도 적용할 수 없음

 

3.reinterpret_cast()

static보다는 강력하지만 안전성이 떨어짐

(C++타입규칙에서 허용하지 않더라도 상황에 따라 캐스팅하는것이 적합할 때 사용 가능)

 마찬가지로 상속 계층에서 아무런 관련이 없는 포인터 타입끼리도 변환할 수 있음

이런 포인터는 흔히 void* 타입으로 캐스팅

 

class X{};
class Y{};

int main()
{
	X x;
    Y y;
    X* xp{*x};
    Y* yp{*y};
    
    xp = reinterpret_cast<X*>(yp);
    void* p{xp};
    xp = reinterpret_cast<X*>(p);
    
    X& xr{x};
    Y& yr{reinterpret_cast<Y&>(x)};
}

 

포인터를 정수형 타입으로 변환하거나 그 반대로 변환할 때도 reinterpret_cast()를 사용할 수 있음.

단 이때 정수형의 크기가 포인터를 담을 정도로 충분히 커야 함

 

4.dynamic_Cast()
같은 상속계층에 속한 타입끼리 캐스팅할 떄 실행시간에 타입을 검사

포인터,레퍼런스를 캐스팅할때 이를 이용

내부 객체타입정보를 실행시간에 검사, 캐스팅하는것이 적합하지 않다고 판단 시 포인터에 대해 널포인터를 리턴/

래퍼런스에 대해서는 bad_cast 예외를 발생시킴

int main()
{
	Base* b;
    Derived* b{new Derived{}};
    b = d;
    d = dynamic_cast<Derived*>(b);
}

 

728x90

'CS > C++' 카테고리의 다른 글

c++ typedef vs using 키워드 차이점  (0) 2023.12.14
C++ template 장단점  (0) 2023.12.14
<algorithm> 헤더의 sort와 list.sort  (0) 2023.12.14
map과 unordered_map 차이  (0) 2023.12.13
상등성과 동등성 차이  (0) 2023.12.13