C++: "... is not a polymorphic type" while using boost::dynamic_pointer_cast

23,939

Solution 1

dynamic_cast works ONLY with polymorphic class. And polymorphic class is that which has atleast one virtual function, even be it the destructor.

//polymorphic classes
struct A
{
   virtual ~A(); //even virtual destructor makes a class polymorphic!
};
struct B : A
{
   void f();
};

//non-polymorphic classes    
struct C
{
   ~C(); //not virtual
};

struct D : C
{
   void f(); //not virtual either
};

In the above code, A and B are polymorphic classes, but C and D are not.

A *pA = new B();
B *pB = dynamic_cast<B*>(pA); //okay

C *pC = new D();
D *pD = dynamic_cast<D*>(pC);  //error -  not polymorphic class

Note that in dynamic_cast, only the source type need to be polymorphic in order to compile. If the destination isn't polymorphic, then dynamic_cast will return null pointer.

D *pD = dynamic_cast<D*>(pA);  //okay - source (pA) is polymorphic

if ( pD )  
      cout << "pD is not null" ;
else 
      cout << "pD is null";

Output:

pD is null

Online demo: https://web.archive.org/web/20000000000000/http://www.ideone.com/Yesxc

Solution 2

'dynamic_cast' : 'my_namespace::A' is not a polymorphic type because it doesn't define or inherit a single virtual function. Just add a virtual destructor and you'll be fine.

dynamic_cast works only for such 'polymorphic' types.

Solution 3

struct A has no virtual methods (not even a destructor), so you can't dynamic_cast from A* - only pointers to types with at least one virtual member function can be used dynamic_cast on. boost::dynamic_pointer_cast does dynamic_cast inside, to it's subject to same requirements.

Share:
23,939
Jonathan Livni
Author by

Jonathan Livni

python, django, C++ and other vegetables...

Updated on October 09, 2020

Comments

  • Jonathan Livni
    Jonathan Livni over 3 years

    Why do I receive the following error for the following code?

    1>C:\Libs\boost_1_44\boost/smart_ptr/shared_ptr.hpp(259): error C2683: 'dynamic_cast' : 'my_namespace::A' is not a polymorphic type
    1>          D:\[location]\[header_filename].h(35) : see declaration of 'my_namespace::A'
    1>          C:\Libs\boost_1_44\boost/smart_ptr/shared_ptr.hpp(522) : see reference to function template instantiation 'boost::shared_ptr<T>::shared_ptr<my_namespace::A>(const boost::shared_ptr<my_namespace::A> &,boost::detail::dynamic_cast_tag)' being compiled
    1>          with
    1>          [
    1>              T=my_namespace::B
    1>          ]
    1>          [location]\[source_filename].cpp(217) : see reference to function template instantiation 'boost::shared_ptr<T> boost::dynamic_pointer_cast<my_namespace::B,striker::A>(const boost::shared_ptr<my_namespace::A> &)' being compiled
    1>          with
    1>          [
    1>              T=my_namespace::B
    1>          ]
    1>C:\Libs\boost_1_44\boost/smart_ptr/shared_ptr.hpp(260): fatal error C1903: unable to recover from previous error(s); stopping compilation
    

    The C++ code is more or less the following:

    #include <list>
    #include "boost/pointer_cast.hpp"
    #include "boost/shared_ptr.hpp"
    
    struct A
    {
    public:
        A(const MyEnum an_enum_, const int an_int_) :
            an_enum(an_enum_),
            an_int(an_int_)
        {}
    
        const MyEnum an_enum;
        const int an_int;
    };
    
    struct B : public A {
    public:
        B(const int some_int_, const MyStruct &a_struct_) :
            A(ENUM_OPTION_A, an_int_),
            a_struct(a_struct_)
        {}
    
        const MyStruct a_struct;
    };
    
    
    // Ussage in some function:
    // ...
    boost::shared_ptr<A> a_ptr = boost::shared_ptr<A>( new B() );
    std::list<boost::shared_ptr<A>> a_list;
    a_list.push_back(a_ptr);
    // ...
    boost::shared_ptr<A> a_ptr2 = a_list.front();
    boost::shared_ptr<B> b_ptr = boost::dynamic_pointer_cast<B>(a_ptr2); // <-- error here
    // ...