Share via


dynamic_cast 연산자

피연산자가 변환 expression 형식의 개체에 type-id.

dynamic_cast < type-id > ( expression )

설명

type-id 에 대 한 포인터 또는 이전에 정의한 클래스 형식에 대 한 참조 또는 "포인터" void 하 여야 합니다.종류를 expression 경우에 대 한 포인터 이어야 합니다 type-id 경우는 포인터나 l-value입니다 type-id 에 대 한 참조입니다.

참조 하십시오 static_cast 에 대 한 정적 및 동적 캐스팅 변환 사이 및 사용 가능한 경우 차이점에 설명 합니다.

동작에는 두 가지 주요 변경 사항 dynamic_cast 관리 되는 코드에서:

  • dynamic_castboxed 열거형의 내부 형식에 대 한 포인터를이 변환 된 포인터 대신 0 반환 런타임에 실패 합니다.

  • dynamic_cast더 이상 예외를 throw 하면 type-id 실행 시 실패 캐스팅은 값 형식에 내부 포인터입니다.이제 캐스팅 throw 하는 대신 포인터가 0 값을 반환 합니다.

경우 type-id 에 명확한 액세스할 수 직접 또는 간접 기본 클래스의 포인터입니다 expression, 고유한 하위 개체 형식에 대 한 포인터 type-id 결과입니다.예를 들면 다음과 같습니다.

// dynamic_cast_1.cpp
// compile with: /c
class B { };
class C : public B { };
class D : public C { };

void f(D* pd) {
   C* pc = dynamic_cast<C*>(pd);   // ok: C is a direct base class
                                   // pc points to C subobject of pd 
   B* pb = dynamic_cast<B*>(pd);   // ok: B is an indirect base class
                                   // pb points to B subobject of pd
}

파생 클래스에서 파생 된 클래스에는 클래스 계층 구조 위로 포인터를 이동 하기 때문에 이러한 유형의 변환에 "업캐스팅은" 라고 합니다.업캐스팅이는 암시적 변환입니다.

경우 type-id 는 void * 실제 유형을 확인 하는 런타임 검사가 수행 됩니다 expression.결과 전체 개체를 가리키는 포인터입니다 expression.예를 들면 다음과 같습니다.

// dynamic_cast_2.cpp
// compile with: /c /GR
class A {virtual void f();};
class B {virtual void f();};

void f() {
   A* pa = new A;
   B* pb = new B;
   void* pv = dynamic_cast<void*>(pa);
   // pv now points to an object of type A

   pv = dynamic_cast<void*>(pb);
   // pv now points to an object of type B
}

경우 type-id 아닙니다 void * 런타임 검사 한 개체를 가리키는 경우를 참조 하십시오. expression 가 가리키는 형식으로 변환 될 수 있습니다 type-id.

경우의 종류 expression 기본 클래스 형식입니다 type-id, 하는 런타임 검사가 수행 됩니다 expression 실제로 가리키는 형식의 전체 개체에 type-id.이 true 이면 결과 완전 한 개체의 형식에 대 한 포인터입니다. type-id.예를 들면 다음과 같습니다.

// dynamic_cast_3.cpp
// compile with: /c /GR
class B {virtual void f();};
class D : public B {virtual void f();};

void f() {
   B* pb = new D;   // unclear but ok
   B* pb2 = new B;

   D* pd = dynamic_cast<D*>(pb);   // ok: pb actually points to a D
   D* pd2 = dynamic_cast<D*>(pb2);   // pb2 points to a B not a D
}

이 유형의 변환 이라고는 "다운" 클래스에 지정 된 클래스의 클래스 계층 구조를 포인터를 이동 하기 때문에 여기에서 파생 됩니다.

다중 상속의 경우에는 모호성을 가능성이 발생 합니다.다음 그림에 클래스 계층 구조를 고려해 야 합니다.

CLR 형식에 대 한 dynamic_cast 변환을 암시적으로 수행할 수 있다면 아무 나는 MSIL의 결과 isinst 동적 검사를 수행 하 고 반환 명령 nullptr 변환이 실패 한 경우.

다음 샘플 사용 dynamic_cast 특정 형식의 인스턴스는 클래스 인지 확인 합니다.

// dynamic_cast_clr.cpp
// compile with: /clr
using namespace System;

void PrintObjectType( Object^o ) {
   if( dynamic_cast<String^>(o) )
      Console::WriteLine("Object is a String");
   else if( dynamic_cast<int^>(o) )
      Console::WriteLine("Object is an int");
}

int main() {
   Object^o1 = "hello";
   Object^o2 = 10;

   PrintObjectType(o1);
   PrintObjectType(o2);
}

다중 상속을 보여 주는 클래스 계층 구조

복수 상속을 보여 주는 클래스 계층 구조

개체 형식에 대 한 포인터 D 를 안전 하 게 캐스팅 될 수 있습니다 B 또는 C.그러나 경우 D 가리키도록 캐스팅는 A 개체는 인스턴스를 A 될 수 있습니까?이 모호한 캐스팅 오류가 발생 합니다.이 문제를 해결 하려면 두 개의 모호 하지 않은 캐스트를 수행할 수 있습니다.예를 들면 다음과 같습니다.

// dynamic_cast_4.cpp
// compile with: /c /GR
class A {virtual void f();};
class B {virtual void f();};
class D : public B {virtual void f();};

void f() {
   D* pd = new D;
   B* pb = dynamic_cast<B*>(pd);   // first cast to B
   A* pa2 = dynamic_cast<A*>(pb);   // ok: unambiguous
}

가상 기본 클래스를 사용 하면 더 이상 모호함을 알아낼 수 있습니다.다음 그림에 클래스 계층 구조를 고려해 야 합니다.

가상 기본 클래스를 보여 주는 클래스 계층 구조

ClassHierarchyVirtualBaseClasses 그래픽

이 계층 구조에서 A 가상 기본 클래스입니다.참조 하십시오 가상 기본 클래스 가상 기본 클래스를 정의 합니다.클래스의 인스턴스가 지정 E 가리키는 포인터는 A 하위 개체에는 dynamic_cast 에 대 한 포인터를 B 모호성 때문에 실패 합니다.먼저 다시 전체를 캐스팅 해야 E 개체를 다음 계층 구조를 다시 해 올바른 도달 모호 하지 않은 방식으로 작동 B 개체입니다.

다음 그림에 클래스 계층 구조를 고려해 야 합니다.

클래스 계층 구조 복제 표시 된 기본 클래스

중복 기본 클래스를 보여 주는 클래스 계층 구조

형식의 개체를 지정 된 E 와에 대 한 포인터는 D 하위 개체를 탐색 합니다,의 D 하위 개체의 맨 왼쪽에 A subobject, 세 가지 변환 될 수 있습니다.수행할 수 있습니다는 dynamic_cast 에서 변환은 D 에 대 한 포인터는 E 포인터를 다음으로 변환 (두 dynamic_cast 또는 암시적 변환)에서 E 에 B, 및 마지막으로 암시적 변환이 B 에 A.예를 들면 다음과 같습니다.

// dynamic_cast_5.cpp
// compile with: /c /GR
class A {virtual void f();};
class B : public A {virtual void f();};
class C : public A { };
class D {virtual void f();};
class E : public B, public C, public D {virtual void f();};

void f(D* pd) {
   E* pe = dynamic_cast<E*>(pd);
   B* pb = pe;   // upcast, implicit conversion
   A* pa = pb;   // upcast, implicit conversion
}

dynamic_cast 연산자도 사용할 수 있습니다 "크로스 캐스팅" 수행할 수 같은 클래스 계층 구조를 사용 하 여 포인터를 예를 들어에서 캐스팅할 수 있습니다는 B subobject에 있는 D subobject에서 완전 한 개체 형식으로 E.

크로스 캐스팅을 고려할 때는 실제로 변환에 대 한 포인터를 수행할 수 있습니다 D 맨 왼쪽 포인터를 A 는 두 단계에서 하위 개체입니다.십자형에서 캐스팅을 수행할 수 있습니다 D 에 B, 다음 암시적 변환이 B 에 A.예를 들면 다음과 같습니다.

// dynamic_cast_6.cpp
// compile with: /c /GR
class A {virtual void f();};
class B : public A {virtual void f();};
class C : public A { };
class D {virtual void f();};
class E : public B, public C, public D {virtual void f();};

void f(D* pd) {
   B* pb = dynamic_cast<B*>(pd);   // cross cast
   A* pa = pb;   // upcast, implicit conversion
}

Null 포인터 값이 null 포인터 값을 대상 형식으로 변환 됩니다 dynamic_cast.

사용 하는 경우 dynamic_cast < type-id > ( expression )경우, expression 형식으로 안전 하 게 변환할 수 없습니다. type-id, 런타임 검사 실패 캐스팅 하면 됩니다.예를 들면 다음과 같습니다.

// dynamic_cast_7.cpp
// compile with: /c /GR
class A {virtual void f();};
class B {virtual void f();};

void f() {
   A* pa = new A;
   B* pb = dynamic_cast<B*>(pa);   // fails at runtime, not safe;
   // B not derived from A
}

실패 한 포인터 형식으로 캐스팅은 null 포인터입니다.실패 한 캐스트 형식을 throw를 참조 하는 bad_cast 예외.   경우 expression 가리키고 하거나 유효한 개체를 참조 하지는 __non_rtti_object 예외가 throw 됩니다.

참조 하십시오 typeid 에 대 한 설명을 __non_rtti_object 예외입니다.

예제

다음 샘플 (C 구조체) 개체에 기본 클래스 (구조체 A) 포인터를 만듭니다.이 더한 존재 사실을 가상 함수, 런타임 다형성을 있습니다.

샘플 또한 계층 구조에서 가상 함수를 호출합니다.

// dynamic_cast_8.cpp
// compile with: /GR /EHsc
#include <stdio.h>
#include <iostream>

struct A {
    virtual void test() {
        printf_s("in A\n");
   }
};

struct B : A {
    virtual void test() {
        printf_s("in B\n");
    }

    void test2() {
        printf_s("test2 in B\n");
    }
};

struct C : B {
    virtual void test() {
        printf_s("in C\n");
    }

    void test2() {
        printf_s("test2 in C\n");
    }
};

void Globaltest(A& a) {
    try {
        C &c = dynamic_cast<C&>(a);
        printf_s("in GlobalTest\n");
    }
    catch(std::bad_cast) {
        printf_s("Can't cast to C\n");
    }
}

int main() {
    A *pa = new C;
    A *pa2 = new B;

    pa->test();

    B * pb = dynamic_cast<B *>(pa);
    if (pb)
        pb->test2();

    C * pc = dynamic_cast<C *>(pa2);
    if (pc)
        pc->test2();

    C ConStack;
    Globaltest(ConStack);

   // will fail because B knows nothing about C
    B BonStack;
    Globaltest(BonStack);
}
  

참고 항목

참조

캐스팅 연산자

C + + 키워드