2009-02-06 43 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; 

    } 

错误:无法将dynamic_cast`(&一) - >性病:: auto_ptr的< _TP> ::得到()const的为什么auto_ptr的dynamic_cast失败?

+0

哪里的:: get()声明? – cbrulak 2009-02-06 03:44:02

回答

11

好,std::auto_ptr<B>不是从std::auto_ptr<A>的。但B源自A。 auto_ptr不知道那个(它不是那么聪明)。看起来你想使用共享所有者指针。 boost::shared_ptr是理想的,它也提供了一个dynamic_pointer_cast:

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

对于auto_ptr的,这样的事情不能真正发挥作用。因为所有权将转移到b。但如果演员失败,b不能获得所有权。我不清楚该怎么做。你可能不得不说,如果演员失败,a会继续拥有所有权 - 这听起来像会造成严重的麻烦。最好使用shared_ptr开始。无论ab然后将指向同一个对象 - 但B作为shared_ptr<B>ashared_ptr<A>

5

动态转换不工作的方式。 A : public B并不意味着auto_ptr<A> : public auto_ptr<B>。这就是为什么助推的shared_ptr提供shared_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*

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

这仍然无法编译,因为AB并不多态类型。 A需要有一个虚拟函数以使类型变为多态。这将编译,但演员只会抛出std::bad_cast,因为它不是真的B*

即使它是一个B*,它会以可怕的方式失败,如果你尝试使用它std::auto_ptr s ab将假定他们拥有该对象并在以后释放它,导致各种内存损坏。演员成功后您可能想要使用a.release()

0

我想C++在vtable中存储RTTI(运行时类型信息)。因此,为了使用dynamic_cast <>实例对象,该对象需要'vtable'。只有当至少有一个函数在类中被声明为“虚拟”时,C++才会创建vtable。

A类和B类没有虚拟功能。这可能是dynamic_cast失败的原因。尝试在基类中声明一个虚拟析构函数。