2009-02-06 6 views
6
#include "iostream" 

    class A { 
     private: 
     int a; 
     public : 

     A(): a(-1) {} 
     int getA() { 
      return a; 
     } 

    }; 

    class A; 

    class B : public A { 
     private: 
     int b; 
     public: 

     B() : b(-1) {} 

     int getB() { 
      return b; 
     } 

    }; 

    int main() { 
     std::auto_ptr<A> a = new A(); 

     std::auto_ptr<B> b = dynamic_cast<std::auto_ptr<B> > (a); 

     return 0; 

    } 

ERROR : -> 표준 : : auto_ptr은 < _Tp> :: 얻을() const를auto_ptr의 dynamic_cast가 실패하는 이유는 무엇입니까?

+0

:: get()에 대한 선언은 어디에 있습니까? – cbrulak

답변

11

웰, std::auto_ptr<B>std::auto_ptr<A>로부터 유도되지 않는다. 그러나 BA에서 파생됩니다. auto_ptr은 그것에 대해 알지 못합니다 (영리하지는 않습니다). 공유 소유권 포인터를 사용하려는 것 같습니다. auto_ptr은 들어, 일이 정말 작동하지 않을 수

boost::shared_ptr<A> a = new A(); 
boost::shared_ptr<B> b = dynamic_pointer_cast<B> (a); 

: boost::shared_ptr는 또한 dynamic_pointer_cast을 제공 이상적입니다. 소유권이 b으로 이동하기 때문입니다. 그러나 캐스트가 실패하면 b는 소유권을 얻을 수 없습니다. 나에게 무엇을해야하는지 명확하지 않습니다. 아마도 캐스트가 실패하면 소유권을 유지할 것입니다 - 심각한 문제를 일으키는 것처럼 들리 겠지요. shared_ptr을 사용하는 것이 가장 좋습니다. ab 다음 동일한 개체를 가리키는 것 모두 -하지만 Bshared_ptr<B> A와와 ashared_ptr<A>

1

그 이유는 auto_ptr은 실제로 포인터되지이다 (&가)`dynamic_cast는 없습니다. 그것은 포인터 래퍼이지만 실제로는 포인터가 아닌 스마트 포인터입니다. dynamic_cast에 템플릿 스타일 인수로 전달되는 유형은 참 포인터 (또는 참조) 유형이어야합니다.

http://msdn.microsoft.com/en-us/library/cby9kycs(VS.80).aspx

5

동적 캐스트는 그런 식으로 작동하지 않습니다. A : public Bauto_ptr<A> : public auto_ptr<B>을 의미하지 않습니다. 이것이 부스트의 shared_ptrshared_dynamic_cast을 제공하는 이유입니다. 당신은 불구하고 auto_ptr 동적 캐스트를 작성할 수

template<typename R, typename T> 
std::auto_ptr<R> auto_ptr_dynamic_cast(std::auto_ptr<T>& in) { 
    auto_ptr<R> rv; 
    R* p; 
    if(p = dynamic_cast<R*>(in.get())) { 
     in.release(); 
     rv = p; 
    } 
    return rv; 

}

그냥 여기에 어떤 일이 일어나는지에 유의하십시오. auto_ptr에는 소유권 의미가 있기 때문에 성공적인 다운 캐스팅은 더 일반적으로 입력 된 원본을 의미하며 auto_ptr에는 더 이상 소유권이 없습니다.

0

A* (a.get()에 의해 반환 됨)을 std::auto_ptr<B>으로 캐스팅하려는 경우 두 번째가 포인터 유형조차도 아니기 때문에 실패합니다. 아마 당신은 B*로 캐스팅 할 : AB 다형성 유형이 아니기 때문에

std::auto_ptr<A> a(new A()); 
std::auto_ptr<B> b(dynamic_cast<B*>(a.get())); 

이 여전히 컴파일되지 않습니다. A에는 유형을 다형성으로 만들기 위해 가상 함수가 있어야합니다. 이것은 컴파일되지만 캐스트는 단지 B*이 아니므로 std::bad_cast을 던집니다.

B*, 이라고해도을 사용하려고하면 끔찍한 방법으로 실패합니다. std::auto_ptrsab 모두 개체를 소유하고 나중에 해제하여 모든 종류의 메모리 손상을 초래할 것으로 예상됩니다. 형 변환이 성공한 후에 a.release()을 사용하고 싶을 것입니다.

0

저는 C++이 vtable에 RTTI (런타임 유형 정보)를 저장한다고 생각합니다. 그러므로 인스턴스 객체와 함께 dynamic_cast <>을 사용하려면 객체에 'vtable'이 있어야합니다. C++은 하나 이상의 함수가 클래스에서 '가상'으로 선언 된 경우에만 vtable을 만듭니다.

클래스 A와 클래스 B에는 가상 기능이 없습니다. 이것은 dynamic_cast 실패의 원인 일 수 있습니다. 기본 클래스에서 가상 소멸자를 선언 해보십시오.

관련 문제