ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Cast 연산자
    C++ 2014. 1. 22. 02:31
    1. const 캐스팅

       

      포인터 또는 참조형의 상수(const)성을 제거하는데 사용한다.

      다른 용도로 사용하지 못하며 다른 캐스트 연산자는 상수성을 제거할 수 없다. 당연한 말이지만 설계에서 이것을 사용하는 것은 바람직하지 못하며 해당 프로그램 전체가 const를 유지하도록 설계하도록 해야 한다. 그러나 다른 라이브러리를 사용해야 하는 경우 부득히 사용하여야만 할 때 사용한다.

      const int* pConstInt = new int( 10 );

      // int* pInt 에 상수화가 제거된 int* pConstInt 대입

      int* pInt = const_cast<int*>( pConstInt );

    2. static_cast

      C style의 Type Casting

      1. 사용 제한사항

        - 실수형과 정수형, 정수형과 열거형등의 기본데이터 타입간의 변화

        - 상속관계 클래스 계층 간의 변화

        1) 런타임 타입 검사를 하지 않음

        2) 다형성이 없어도 변환 가능 ( RTTI 옵션이 꺼져 있어도 사용 가능 )

        3) 다중 상속에서 기본 클래스 간의 타입 변환은 못함

        - void 포인터를 다른 타입의 포인터로 변환

        - 서로 다른 타입의 포인터 간의 타입변환 불가

        서로 다른 타입의 포인터 간의 타입 변환에는 void 포인터를 경유하는 방식을 추천

        변환하려는 포인터가 계층 관계에 있다면 어떤 값을 가지고 있던지 컴파일은 성공한다.

        문제는 런타임에 발생할 것이고 대부분의 프로그램이 다운된다.

        이런 문제점 때문에 클래스 계층 간의 타입 변환에 Dynamic_Cast를 추천한다.

         

    3. Dynamic Cast

      dynamic_cast 는 상속 관계 안에서 포인터나 참조자의 타입을 기본 클래스에서 파생클래스로의 다운 캐스팅과 다중 상속에서 기본 클래스 간의 안전한 타입 캐스팅에 사용된다. Polymorphism을 이용한 상속관계에서 안전한 타입 캐스팅을 사용하고 할 때 사용한다. 안전한 타입캐스팅이란 런타임에 타입검사를 한다는 것이다.
      const_cast와 같인 다른 용도로는 사용하지 못하며 용도가 명확하다.

      객체가 위치한 메모리의 시작 부분을 찾는데도 사용될 수 있다.

      ex) 객체를 void* 로 dynamic_cast 하면 시작 주소가 나온다.

      void* pV = dynamic_cast<void*>( 객체포인터 );

     

    dynamic_cast 제한 사항

    - 상속 관계 안에서만 사용할 수 있다.

    - 하나 이상의 가상함수를 가지고 있어야 한다.

    - 컴파일러의 RTTI 설정이 켜져 있어야 한다.

     

    dynamic_cast 예제

    #include <iostream>

    using namespace std;

    class Base

    {

    public :

    virtual void Put( void )

    {

         cout << "Base" << endl;

    }

    };

     

    class Derived : public Base

    {

    public :

    void Put( void )

    {

    cout << "Derived" << endl;

    }

    };

    int main( int argc, char* argv[] )

    {

    Base* pBase = new Base;

    Base* pDerived1 = new Derived;

    Derived* pDerived2 = new Derived;

    Derived* pDerived = NULL;

     

    // 컴파일 오류 : 타입변환 불가

    // pDerived = pBase;

     

    // 컴파일 성공 : 런타임에 타입변환에 실패하여 NULL 리턴

    pDerived = dynamic_cast<Derived*>( pBase );

    if( pDerived == NULL )

    {

    cout << "Runtime ERROR" << endl;

    }

     

    // 컴파일 오류 : 타입변환 불가

    // pDerived = pDerived1;

     

    // 컴파일 성공 : 런타임에 타입변환에 성공하여 Derived타입의 포인터 리턴

    pDerived = dynamic_cast<Derived*>( pDerived1 );

    if( pDerived )

    {

    pDerived->Put();

    }

    Base b;

    Derived d;

    Base& bb = b;


    try {

    d= dynamic_cast<Derived&> (bb);

    }

    catch (const std::bad_cast) {

    cout << "Bad Cast" << endl;

    }

    // 컴파일 성공 : 이런 경우에는 캐스팅이 필요 없다

    pDerived = pDerived2;

    return 0;

    }

    [출처] dynamic_cast|작성자 바람늑대

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

    Copy Constructor vs Assignment operator  (0) 2014.02.12
    Constructor 와 메모리  (0) 2014.02.12
    RTTI : Run-time type information 사용예  (0) 2014.01.18
    Template 사용  (0) 2014.01.16
    Friend의 사용시기  (0) 2014.01.14
Designed by Tistory.